1010import lazy_loader as lazy
1111
1212
13+ @pytest .fixture
14+ def clean_fake_pkg ():
15+ yield
16+ sys .modules .pop ("tests.fake_pkg.some_func" , None )
17+ sys .modules .pop ("tests.fake_pkg" , None )
18+ sys .modules .pop ("tests" , None )
19+
20+
21+ @pytest .mark .parametrize ("attempt" , [1 , 2 ])
22+ def test_cleanup_fixture (clean_fake_pkg , attempt ):
23+ assert "tests.fake_pkg" not in sys .modules
24+ assert "tests.fake_pkg.some_func" not in sys .modules
25+ from tests import fake_pkg
26+
27+ assert "tests.fake_pkg" in sys .modules
28+ assert "tests.fake_pkg.some_func" not in sys .modules
29+ assert isinstance (fake_pkg .some_func , types .FunctionType )
30+ assert "tests.fake_pkg.some_func" in sys .modules
31+
32+
1333def test_lazy_import_basics ():
1434 math = lazy .load ("math" )
1535 anything_not_real = lazy .load ("anything_not_real" )
1636
1737 # Now test that accessing attributes does what it should
1838 assert math .sin (math .pi ) == pytest .approx (0 , 1e-6 )
1939 # poor-mans pytest.raises for testing errors on attribute access
20- try :
40+ with pytest . raises ( ModuleNotFoundError ) :
2141 anything_not_real .pi
22- raise AssertionError () # Should not get here
23- except ModuleNotFoundError :
24- pass
2542 assert isinstance (anything_not_real , lazy .DelayedImportErrorModule )
2643 # see if it changes for second access
27- try :
44+ with pytest . raises ( ModuleNotFoundError ) :
2845 anything_not_real .pi
29- raise AssertionError () # Should not get here
30- except ModuleNotFoundError :
31- pass
3246
3347
3448def test_lazy_import_subpackages ():
@@ -68,11 +82,8 @@ def test_lazy_import_nonbuiltins():
6882 if not isinstance (np , lazy .DelayedImportErrorModule ):
6983 assert np .sin (np .pi ) == pytest .approx (0 , 1e-6 )
7084 if isinstance (sp , lazy .DelayedImportErrorModule ):
71- try :
85+ with pytest . raises ( ModuleNotFoundError ) :
7286 sp .pi
73- raise AssertionError ()
74- except ModuleNotFoundError :
75- pass
7687
7788
7889def test_lazy_attach ():
@@ -103,6 +114,26 @@ def test_lazy_attach():
103114 if v is not None :
104115 assert locls [k ] == v
105116
117+ # Exercise __getattr__, though it will just error
118+ with pytest .raises (ImportError ):
119+ locls ["__getattr__" ]("mysubmodule" )
120+
121+ # Attribute is supposed to be imported, error on submodule load
122+ with pytest .raises (ImportError ):
123+ locls ["__getattr__" ]("some_var_or_func" )
124+
125+ # Attribute is unknown, raise AttributeError
126+ with pytest .raises (AttributeError ):
127+ locls ["__getattr__" ]("unknown_attr" )
128+
129+
130+ def test_lazy_attach_noattrs ():
131+ name = "mymod"
132+ submods = ["mysubmodule" , "anothersubmodule" ]
133+ _ , _ , all_ = lazy .attach (name , submods )
134+
135+ assert all_ == sorted (submods )
136+
106137
107138def test_lazy_attach_returns_copies ():
108139 _get , _dir , _all = lazy .attach (
@@ -127,18 +158,24 @@ def test_lazy_attach_returns_copies():
127158 assert _all == [* expected , "modify_returned_all" ]
128159
129160
130- def test_attach_same_module_and_attr_name ():
131- from tests import fake_pkg
161+ @pytest .mark .parametrize ("eager_import" , [False , True ])
162+ def test_attach_same_module_and_attr_name (clean_fake_pkg , eager_import ):
163+ env = {}
164+ if eager_import :
165+ env ["EAGER_IMPORT" ] = "1"
132166
133- # Grab attribute twice, to ensure that importing it does not
134- # override function by module
135- assert isinstance (fake_pkg .some_func , types .FunctionType )
136- assert isinstance (fake_pkg .some_func , types .FunctionType )
167+ with mock .patch .dict (os .environ , env ):
168+ from tests import fake_pkg
137169
138- # Ensure imports from submodule still work
139- from tests .fake_pkg .some_func import some_func
170+ # Grab attribute twice, to ensure that importing it does not
171+ # override function by module
172+ assert isinstance (fake_pkg .some_func , types .FunctionType )
173+ assert isinstance (fake_pkg .some_func , types .FunctionType )
140174
141- assert isinstance (some_func , types .FunctionType )
175+ # Ensure imports from submodule still work
176+ from tests .fake_pkg .some_func import some_func
177+
178+ assert isinstance (some_func , types .FunctionType )
142179
143180
144181FAKE_STUB = """
@@ -196,6 +233,10 @@ def test_require_kwarg():
196233 math = lazy .load ("math" , require = "somepkg >= 2.0" )
197234 assert isinstance (math , lazy .DelayedImportErrorModule )
198235
236+ # Eager failure
237+ with pytest .raises (ModuleNotFoundError ):
238+ lazy .load ("math" , require = "somepkg >= 2.0" , error_on_import = True )
239+
199240 # When a module can be loaded but the version can't be checked,
200241 # raise a ValueError
201242 with pytest .raises (ValueError ):
0 commit comments