test_optional_dependency.py 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. import sys
  2. import types
  3. import pytest
  4. from pandas.compat._optional import (
  5. VERSIONS,
  6. import_optional_dependency,
  7. )
  8. import pandas._testing as tm
  9. def test_import_optional():
  10. match = "Missing .*notapackage.* pip .* conda .* notapackage"
  11. with pytest.raises(ImportError, match=match) as exc_info:
  12. import_optional_dependency("notapackage")
  13. # The original exception should be there as context:
  14. assert isinstance(exc_info.value.__context__, ImportError)
  15. result = import_optional_dependency("notapackage", errors="ignore")
  16. assert result is None
  17. def test_xlrd_version_fallback():
  18. pytest.importorskip("xlrd")
  19. import_optional_dependency("xlrd")
  20. def test_bad_version(monkeypatch):
  21. name = "fakemodule"
  22. module = types.ModuleType(name)
  23. module.__version__ = "0.9.0"
  24. sys.modules[name] = module
  25. monkeypatch.setitem(VERSIONS, name, "1.0.0")
  26. match = "Pandas requires .*1.0.0.* of .fakemodule.*'0.9.0'"
  27. with pytest.raises(ImportError, match=match):
  28. import_optional_dependency("fakemodule")
  29. # Test min_version parameter
  30. result = import_optional_dependency("fakemodule", min_version="0.8")
  31. assert result is module
  32. with tm.assert_produces_warning(UserWarning):
  33. result = import_optional_dependency("fakemodule", errors="warn")
  34. assert result is None
  35. module.__version__ = "1.0.0" # exact match is OK
  36. result = import_optional_dependency("fakemodule")
  37. assert result is module
  38. def test_submodule(monkeypatch):
  39. # Create a fake module with a submodule
  40. name = "fakemodule"
  41. module = types.ModuleType(name)
  42. module.__version__ = "0.9.0"
  43. sys.modules[name] = module
  44. sub_name = "submodule"
  45. submodule = types.ModuleType(sub_name)
  46. setattr(module, sub_name, submodule)
  47. sys.modules[f"{name}.{sub_name}"] = submodule
  48. monkeypatch.setitem(VERSIONS, name, "1.0.0")
  49. match = "Pandas requires .*1.0.0.* of .fakemodule.*'0.9.0'"
  50. with pytest.raises(ImportError, match=match):
  51. import_optional_dependency("fakemodule.submodule")
  52. with tm.assert_produces_warning(UserWarning):
  53. result = import_optional_dependency("fakemodule.submodule", errors="warn")
  54. assert result is None
  55. module.__version__ = "1.0.0" # exact match is OK
  56. result = import_optional_dependency("fakemodule.submodule")
  57. assert result is submodule
  58. def test_no_version_raises(monkeypatch):
  59. name = "fakemodule"
  60. module = types.ModuleType(name)
  61. sys.modules[name] = module
  62. monkeypatch.setitem(VERSIONS, name, "1.0.0")
  63. with pytest.raises(ImportError, match="Can't determine .* fakemodule"):
  64. import_optional_dependency(name)