diff --git a/doc/source/whatsnew/v0.25.0.rst b/doc/source/whatsnew/v0.25.0.rst index f61c8bfbd782e..7d123697d3d20 100644 --- a/doc/source/whatsnew/v0.25.0.rst +++ b/doc/source/whatsnew/v0.25.0.rst @@ -96,7 +96,8 @@ Other Enhancements - :meth:`DataFrame.query` and :meth:`DataFrame.eval` now supports quoting column names with backticks to refer to names with spaces (:issue:`6508`) - :func:`merge_asof` now gives a more clear error message when merge keys are categoricals that are not equal (:issue:`26136`) - :meth:`pandas.core.window.Rolling` supports exponential (or Poisson) window type (:issue:`21303`) -- :class:`DatetimeIndex` and :class:`TimedeltaIndex` now have a `mean` method (:issue:`24757`) +- Error message for missing required imports now includes the original import error's text (:issue:`23868`) +- :class:`DatetimeIndex` and :class:`TimedeltaIndex` now have a ``mean`` method (:issue:`24757`) - :meth:`DataFrame.describe` now formats integer percentiles without decimal point (:issue:`26660`) .. _whatsnew_0250.api_breaking: diff --git a/pandas/__init__.py b/pandas/__init__.py index 4c494b4a62e39..a2fa14be83998 100644 --- a/pandas/__init__.py +++ b/pandas/__init__.py @@ -10,11 +10,10 @@ try: __import__(dependency) except ImportError as e: - missing_dependencies.append(dependency) + missing_dependencies.append("{0}: {1}".format(dependency, str(e))) if missing_dependencies: - raise ImportError( - "Missing required dependencies {0}".format(missing_dependencies)) + raise ImportError("Unable to import required dependencies:\n" + "\n".join(missing_dependencies)) del hard_dependencies, dependency, missing_dependencies # numpy compat diff --git a/pandas/tests/test_downstream.py b/pandas/tests/test_downstream.py index c41c3abcab4af..14d3ee5ac4fe2 100644 --- a/pandas/tests/test_downstream.py +++ b/pandas/tests/test_downstream.py @@ -1,6 +1,7 @@ """ Testing that we work in the downstream packages """ +import builtins import importlib import subprocess import sys @@ -131,3 +132,32 @@ def test_pyarrow(df): table = pyarrow.Table.from_pandas(df) result = table.to_pandas() tm.assert_frame_equal(result, df) + + +def test_missing_required_dependency(monkeypatch): + # GH 23868 + original_import = __import__ + + def mock_import_fail(name, *args, **kwargs): + if name == "numpy": + raise ImportError("cannot import name numpy") + elif name == "pytz": + raise ImportError("cannot import name some_dependency") + elif name == "dateutil": + raise ImportError("cannot import name some_other_dependency") + else: + return original_import(name, *args, **kwargs) + + expected_msg = ( + "Unable to import required dependencies:" + "\nnumpy: cannot import name numpy" + "\npytz: cannot import name some_dependency" + "\ndateutil: cannot import name some_other_dependency" + ) + + import pandas as pd + + with monkeypatch.context() as m: + m.setattr(builtins, "__import__", mock_import_fail) + with pytest.raises(ImportError, match=expected_msg): + importlib.reload(pd)