Skip to content

Commit 60d6f28

Browse files
authored
Fix read parquet import error message (#33361)
1 parent def6f6d commit 60d6f28

File tree

2 files changed

+57
-12
lines changed

2 files changed

+57
-12
lines changed

pandas/io/parquet.py

+13-12
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,23 @@ def get_engine(engine: str) -> "BaseImpl":
1818

1919
if engine == "auto":
2020
# try engines in this order
21-
try:
22-
return PyArrowImpl()
23-
except ImportError:
24-
pass
21+
engine_classes = [PyArrowImpl, FastParquetImpl]
2522

26-
try:
27-
return FastParquetImpl()
28-
except ImportError:
29-
pass
23+
error_msgs = ""
24+
for engine_class in engine_classes:
25+
try:
26+
return engine_class()
27+
except ImportError as err:
28+
error_msgs += "\n - " + str(err)
3029

3130
raise ImportError(
3231
"Unable to find a usable engine; "
3332
"tried using: 'pyarrow', 'fastparquet'.\n"
34-
"pyarrow or fastparquet is required for parquet support"
33+
"A suitable version of "
34+
"pyarrow or fastparquet is required for parquet "
35+
"support.\n"
36+
"Trying to import the above resulted in these errors:"
37+
f"{error_msgs}"
3538
)
3639

3740
if engine == "pyarrow":
@@ -105,9 +108,7 @@ def write(
105108
**kwargs,
106109
)
107110
else:
108-
self.api.parquet.write_table(
109-
table, path, compression=compression, **kwargs,
110-
)
111+
self.api.parquet.write_table(table, path, compression=compression, **kwargs)
111112

112113
def read(self, path, columns=None, **kwargs):
113114
path, _, _, should_close = get_filepath_or_buffer(path)

pandas/tests/io/test_parquet.py

+44
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
except ImportError:
3636
_HAVE_FASTPARQUET = False
3737

38+
3839
pytestmark = pytest.mark.filterwarnings(
3940
"ignore:RangeIndex.* is deprecated:DeprecationWarning"
4041
)
@@ -223,6 +224,49 @@ def test_options_get_engine(fp, pa):
223224
assert isinstance(get_engine("fastparquet"), FastParquetImpl)
224225

225226

227+
def test_get_engine_auto_error_message():
228+
# Expect different error messages from get_engine(engine="auto")
229+
# if engines aren't installed vs. are installed but bad version
230+
from pandas.compat._optional import VERSIONS
231+
232+
# Do we have engines installed, but a bad version of them?
233+
pa_min_ver = VERSIONS.get("pyarrow")
234+
fp_min_ver = VERSIONS.get("fastparquet")
235+
have_pa_bad_version = (
236+
False
237+
if not _HAVE_PYARROW
238+
else LooseVersion(pyarrow.__version__) < LooseVersion(pa_min_ver)
239+
)
240+
have_fp_bad_version = (
241+
False
242+
if not _HAVE_FASTPARQUET
243+
else LooseVersion(fastparquet.__version__) < LooseVersion(fp_min_ver)
244+
)
245+
# Do we have usable engines installed?
246+
have_usable_pa = _HAVE_PYARROW and not have_pa_bad_version
247+
have_usable_fp = _HAVE_FASTPARQUET and not have_fp_bad_version
248+
249+
if not have_usable_pa and not have_usable_fp:
250+
# No usable engines found.
251+
if have_pa_bad_version:
252+
match = f"Pandas requires version .{pa_min_ver}. or newer of .pyarrow."
253+
with pytest.raises(ImportError, match=match):
254+
get_engine("auto")
255+
else:
256+
match = "Missing optional dependency .pyarrow."
257+
with pytest.raises(ImportError, match=match):
258+
get_engine("auto")
259+
260+
if have_fp_bad_version:
261+
match = f"Pandas requires version .{fp_min_ver}. or newer of .fastparquet."
262+
with pytest.raises(ImportError, match=match):
263+
get_engine("auto")
264+
else:
265+
match = "Missing optional dependency .fastparquet."
266+
with pytest.raises(ImportError, match=match):
267+
get_engine("auto")
268+
269+
226270
def test_cross_engine_pa_fp(df_cross_compat, pa, fp):
227271
# cross-compat with differing reading/writing engines
228272

0 commit comments

Comments
 (0)