saulpw / visidata

A terminal spreadsheet multitool for discovering and arranging data
http://visidata.org
GNU General Public License v3.0
7.8k stars 276 forks source link

[texttables] incorrect 'tabulate' module installed with brew #2405

Closed bnisly closed 4 months ago

bnisly commented 4 months ago

Small description Getting AttributeError with version 3.0.2 installed from homebrew

Expected result Visidata opens csv file.

Actual result with screenshot See below.

Steps to reproduce with sample data and a .vd See below.

vd foo.csv Traceback (most recent call last): File "/opt/homebrew/bin/vd", line 3, in import visidata.main File "/opt/homebrew/Cellar/visidata/3.0.2_1/libexec/lib/python3.12/site-packages/visidata/init.py", line 137, in vd.importSubmodules('visidata.loaders') File "/opt/homebrew/Cellar/visidata/3.0.2_1/libexec/lib/python3.12/site-packages/visidata/settings.py", line 495, in importSubmodules vd.importModule(pkgname + '.' + module.name) File "/opt/homebrew/Cellar/visidata/3.0.2_1/libexec/lib/python3.12/site-packages/visidata/settings.py", line 481, in importModule r = importlib.import_module(pkgname) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/homebrew/Cellar/python@3.12/3.12.3/Frameworks/Python.framework/Versions/3.12/lib/python3.12/importlib/init.py", line 90, in import_module return _bootstrap._gcd_import(name[level:], package, level) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/homebrew/Cellar/visidata/3.0.2_1/libexec/lib/python3.12/site-packages/visidata/loaders/texttables.py", line 6, in for fmt in tabulate.tabulate_formats: ^^^^^^^^^^^^^^^^^^^^^^^^^ AttributeError: module 'tabulate' has no attribute 'tabulate_formats'

echo 'foo,bar' | vd Traceback (most recent call last): File "/opt/homebrew/bin/vd", line 3, in import visidata.main File "/opt/homebrew/Cellar/visidata/3.0.2_1/libexec/lib/python3.12/site-packages/visidata/init.py", line 137, in vd.importSubmodules('visidata.loaders') File "/opt/homebrew/Cellar/visidata/3.0.2_1/libexec/lib/python3.12/site-packages/visidata/settings.py", line 495, in importSubmodules vd.importModule(pkgname + '.' + module.name) File "/opt/homebrew/Cellar/visidata/3.0.2_1/libexec/lib/python3.12/site-packages/visidata/settings.py", line 481, in importModule r = importlib.import_module(pkgname) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/homebrew/Cellar/python@3.12/3.12.3/Frameworks/Python.framework/Versions/3.12/lib/python3.12/importlib/init.py", line 90, in import_module return _bootstrap._gcd_import(name[level:], package, level) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/homebrew/Cellar/visidata/3.0.2_1/libexec/lib/python3.12/site-packages/visidata/loaders/texttables.py", line 6, in for fmt in tabulate.tabulate_formats: ^^^^^^^^^^^^^^^^^^^^^^^^^ AttributeError: module 'tabulate' has no attribute 'tabulate_formats'

Additional context brew info visidata ==> saulpw/vd/visidata: stable 3.0.2 Terminal utility for exploring and arranging tabular data https://visidata.org/ Installed /opt/homebrew/Cellar/visidata/3.0.2_1 (880 files, 10.4MB) * Built from source on 2024-05-15 at 11:09:53 From: https://github.com/saulpw/homebrew-vd/blob/HEAD/Formula/visidata.rb ==> Dependencies Required: python3 ✔

bnisly commented 4 months ago

The pip install version works.

conda create -n visidata -y python=3.12
conda activate visidata
pip install visidata

type -a visidata
visidata is /opt/homebrew/Caskroom/miniconda/base/envs/visidata/bin/visidata
visidata is /opt/homebrew/bin/visidata
type -a vd
vd is /opt/homebrew/Caskroom/miniconda/base/envs/visidata/bin/vd
vd is /opt/homebrew/bin/vd

vd foo.csv
saul.pw/VisiData v3.0.2
opening foo.csv as csv
saulpw commented 4 months ago

It looks like astanin/python-tabulate v0.9 as packaged with Brew should have that attribute, so you might have a different version of the tabulate library installed on your system. I've fixed VisiData so at least it doesn't bomb out in this case, but I don't think there's much else we can do.

bnisly commented 4 months ago

Thanks, @saulpw. I brew installed python-tabulate since it was not installed and now it's working.

Do you need to add that as a dependency to visidata?

saulpw commented 4 months ago

We deliberately do not install the dependencies for every format, since that would increase the installation time and footprint substantially. (The brew package installs the deps for xls/xlsx/html and that's all.) If people want to petition for the tabulate savers to be available by default, we can certainly entertain that idea.

But also, I believe you must have had a different tabulate library installed, or it should have blithely ignored it (as a ModuleNotFoundError on the import). Was that not the case?

bnisly commented 4 months ago

Yes, I do. Given the error, how would I know to install python-tabulate?

/usr/local/Cellar:
for i in $(tree -if | grep -w tabulate.py ); do echo $i; grep tabulate_formats $i; done
./grip/4.6.1_1/libexec/lib/python3.10/site-packages/pip/_vendor/rich/tabulate.py
./httpie/3.2.1/libexec/lib/python3.10/site-packages/pip/_vendor/rich/tabulate.py
./mdv/1.7.4/libexec/lib/python3.8/site-packages/mdv/tabulate.py
__all__ = ["tabulate", "tabulate_formats", "simple_separated_format"]
tabulate_formats = list(sorted(_table_formats.keys()))
     'latex', and 'latex_booktabs'. Variable `tabulate_formats` contains the list of
            if value not in tabulate_formats:
./mdv/1.7.4/libexec/lib/python3.8/site-packages/tabulate.py
__all__ = ["tabulate", "tabulate_formats", "simple_separated_format"]
tabulate_formats = list(sorted(_table_formats.keys()))
    'latex', 'latex_raw' and 'latex_booktabs'. Variable `tabulate_formats`
            if value not in tabulate_formats:
./pypy3/7.3.9/libexec/site-packages/pip-22.0.4-py3.7.egg/pip/_vendor/rich/tabulate.py
./rich-cli/1.8.0/libexec/lib/python3.10/site-packages/pip/_vendor/rich/tabulate.py

/opt/homebrew/Cellar:
for i in $(tree -if | grep -w tabulate.py ); do echo $i; grep tabulate_formats $i; done
./mdv/1.7.5/libexec/lib/python3.12/site-packages/mdv/tabulate.py
__all__ = ["tabulate", "tabulate_formats", "simple_separated_format"]
tabulate_formats = list(sorted(_table_formats.keys()))
     'latex', and 'latex_booktabs'. Variable `tabulate_formats` contains the list of
            if value not in tabulate_formats:
saulpw commented 4 months ago

Well, I guess you'd search for the error message and come across this issue. In general I don't want to add specific code to VisiData to show pretty error messages for every possible environmental problem.