Skip to content

Commit 7f8dd72

Browse files
TomAugspurgerjreback
authored andcommitted
CLN: Deduplicate show_versions (#26816)
1 parent fa92585 commit 7f8dd72

File tree

6 files changed

+81
-61
lines changed

6 files changed

+81
-61
lines changed

doc/source/install.rst

+1
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,7 @@ psycopg2 PostgreSQL engine for sqlalchemy
286286
pyarrow 0.9.0 Parquet and feather reading / writing
287287
pymysql MySQL engine for sqlalchemy
288288
pyreadstat SPSS files (.sav) reading
289+
pytables 3.4.2 HDF5 reading / writing
289290
qtpy Clipboard I/O
290291
s3fs 0.0.8 Amazon S3 access
291292
xarray 0.8.2 pandas-like API for N-dimensional data

pandas/compat/_optional.py

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
"s3fs": "0.0.8",
2020
"scipy": "0.19.0",
2121
"sqlalchemy": "1.1.4",
22+
"tables": "3.4.2",
2223
"xarray": "0.8.2",
2324
"xlrd": "1.1.0",
2425
"xlwt": "1.2.0",

pandas/io/pytables.py

+2-5
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
from pandas._libs import lib, writers as libwriters
2121
from pandas._libs.tslibs import timezones
22+
from pandas.compat._optional import import_optional_dependency
2223
from pandas.errors import PerformanceWarning
2324

2425
from pandas.core.dtypes.common import (
@@ -448,11 +449,7 @@ def __init__(self, path, mode=None, complevel=None, complib=None,
448449
if 'format' in kwargs:
449450
raise ValueError('format is not a defined argument for HDFStore')
450451

451-
try:
452-
import tables # noqa
453-
except ImportError as ex: # pragma: no cover
454-
raise ImportError('HDFStore requires PyTables, "{ex!s}" problem '
455-
'importing'.format(ex=ex))
452+
tables = import_optional_dependency("tables")
456453

457454
if complib is not None and complib not in tables.filters.all_complibs:
458455
raise ValueError(
+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import pytest
2+
3+
import pandas.util._test_decorators as td
4+
5+
import pandas as pd
6+
import pandas.util.testing as tm
7+
8+
9+
@td.skip_if_installed("tables")
10+
def test_pytables_raises():
11+
df = pd.DataFrame({"A": [1, 2]})
12+
with pytest.raises(ImportError, match="tables"):
13+
with tm.ensure_clean("foo.h5") as path:
14+
df.to_hdf(path, "df")

pandas/util/_print_versions.py

+46-56
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
import codecs
2-
import importlib
32
import locale
43
import os
54
import platform
65
import struct
76
import subprocess
87
import sys
98

9+
from pandas.compat._optional import (
10+
VERSIONS, _get_version, import_optional_dependency)
11+
1012

1113
def get_sys_info():
1214
"Returns system information as a dict"
@@ -58,60 +60,49 @@ def get_sys_info():
5860

5961
def show_versions(as_json=False):
6062
sys_info = get_sys_info()
61-
6263
deps = [
63-
# (MODULE_NAME, f(mod) -> mod version)
64-
("pandas", lambda mod: mod.__version__),
65-
("pytest", lambda mod: mod.__version__),
66-
("pip", lambda mod: mod.__version__),
67-
("setuptools", lambda mod: mod.__version__),
68-
("Cython", lambda mod: mod.__version__),
69-
("numpy", lambda mod: mod.version.version),
70-
("scipy", lambda mod: mod.version.version),
71-
("pyarrow", lambda mod: mod.__version__),
72-
("xarray", lambda mod: mod.__version__),
73-
("IPython", lambda mod: mod.__version__),
74-
("sphinx", lambda mod: mod.__version__),
75-
("patsy", lambda mod: mod.__version__),
76-
("dateutil", lambda mod: mod.__version__),
77-
("pytz", lambda mod: mod.VERSION),
78-
("blosc", lambda mod: mod.__version__),
79-
("bottleneck", lambda mod: mod.__version__),
80-
("tables", lambda mod: mod.__version__),
81-
("numexpr", lambda mod: mod.__version__),
82-
("feather", lambda mod: mod.__version__),
83-
("matplotlib", lambda mod: mod.__version__),
84-
("openpyxl", lambda mod: mod.__version__),
85-
("xlrd", lambda mod: mod.__VERSION__),
86-
("xlwt", lambda mod: mod.__VERSION__),
87-
("xlsxwriter", lambda mod: mod.__version__),
88-
("lxml.etree", lambda mod: mod.__version__),
89-
("bs4", lambda mod: mod.__version__),
90-
("html5lib", lambda mod: mod.__version__),
91-
("sqlalchemy", lambda mod: mod.__version__),
92-
("pymysql", lambda mod: mod.__version__),
93-
("psycopg2", lambda mod: mod.__version__),
94-
("jinja2", lambda mod: mod.__version__),
95-
("s3fs", lambda mod: mod.__version__),
96-
("fastparquet", lambda mod: mod.__version__),
97-
("pandas_gbq", lambda mod: mod.__version__),
98-
("pandas_datareader", lambda mod: mod.__version__),
99-
("gcsfs", lambda mod: mod.__version__),
64+
'pandas',
65+
# required
66+
'numpy',
67+
'pytz',
68+
'dateutil',
69+
# install / build,
70+
'pip',
71+
'setuptools',
72+
'Cython',
73+
# test
74+
'pytest',
75+
'hypothesis',
76+
# docs
77+
"sphinx",
78+
# Other, need a min version
79+
"blosc",
80+
"feather",
81+
"xlsxwriter",
82+
"lxml.etree",
83+
"html5lib",
84+
"pymysql",
85+
"psycopg2",
86+
"jinja2",
87+
# Other, not imported.
88+
"IPython",
89+
"pandas_datareader",
10090
]
10191

102-
deps_blob = list()
103-
for (modname, ver_f) in deps:
104-
try:
105-
if modname in sys.modules:
106-
mod = sys.modules[modname]
107-
else:
108-
mod = importlib.import_module(modname)
109-
ver = ver_f(mod)
110-
deps_blob.append((modname, ver))
111-
except ImportError:
112-
deps_blob.append((modname, None))
92+
deps.extend(list(VERSIONS))
93+
deps_blob = []
11394

114-
if (as_json):
95+
for modname in deps:
96+
mod = import_optional_dependency(modname,
97+
raise_on_missing=False,
98+
on_version="ignore")
99+
if mod:
100+
ver = _get_version(mod)
101+
else:
102+
ver = None
103+
deps_blob.append((modname, ver))
104+
105+
if as_json:
115106
try:
116107
import json
117108
except ImportError:
@@ -126,16 +117,15 @@ def show_versions(as_json=False):
126117
json.dump(j, f, indent=2)
127118

128119
else:
129-
120+
maxlen = max(len(x) for x in deps)
121+
tpl = '{{k:<{maxlen}}}: {{stat}}'.format(maxlen=maxlen)
130122
print("\nINSTALLED VERSIONS")
131123
print("------------------")
132-
133124
for k, stat in sys_info:
134-
print("{k}: {stat}".format(k=k, stat=stat))
135-
125+
print(tpl.format(k=k, stat=stat))
136126
print("")
137127
for k, stat in deps_blob:
138-
print("{k}: {stat}".format(k=k, stat=stat))
128+
print(tpl.format(k=k, stat=stat))
139129

140130

141131
def main():

pandas/util/_test_decorators.py

+17
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,23 @@ def _skip_if_no_scipy():
100100
safe_import('scipy.signal'))
101101

102102

103+
def skip_if_installed(
104+
package: str,
105+
) -> MarkDecorator:
106+
"""
107+
Skip a test if a package is installed.
108+
109+
Parameters
110+
----------
111+
package : str
112+
The name of the package.
113+
"""
114+
return pytest.mark.skipif(
115+
safe_import(package),
116+
reason="Skipping because {} is installed.".format(package)
117+
)
118+
119+
103120
def skip_if_no(
104121
package: str,
105122
min_version: Optional[str] = None

0 commit comments

Comments
 (0)