10
10
import lazy_loader as lazy
11
11
12
12
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
+
13
33
def test_lazy_import_basics ():
14
34
math = lazy .load ("math" )
15
35
anything_not_real = lazy .load ("anything_not_real" )
16
36
17
37
# Now test that accessing attributes does what it should
18
38
assert math .sin (math .pi ) == pytest .approx (0 , 1e-6 )
19
39
# poor-mans pytest.raises for testing errors on attribute access
20
- try :
40
+ with pytest . raises ( ModuleNotFoundError ) :
21
41
anything_not_real .pi
22
- raise AssertionError () # Should not get here
23
- except ModuleNotFoundError :
24
- pass
25
42
assert isinstance (anything_not_real , lazy .DelayedImportErrorModule )
26
43
# see if it changes for second access
27
- try :
44
+ with pytest . raises ( ModuleNotFoundError ) :
28
45
anything_not_real .pi
29
- raise AssertionError () # Should not get here
30
- except ModuleNotFoundError :
31
- pass
32
46
33
47
34
48
def test_lazy_import_subpackages ():
@@ -68,11 +82,8 @@ def test_lazy_import_nonbuiltins():
68
82
if not isinstance (np , lazy .DelayedImportErrorModule ):
69
83
assert np .sin (np .pi ) == pytest .approx (0 , 1e-6 )
70
84
if isinstance (sp , lazy .DelayedImportErrorModule ):
71
- try :
85
+ with pytest . raises ( ModuleNotFoundError ) :
72
86
sp .pi
73
- raise AssertionError ()
74
- except ModuleNotFoundError :
75
- pass
76
87
77
88
78
89
def test_lazy_attach ():
@@ -103,6 +114,26 @@ def test_lazy_attach():
103
114
if v is not None :
104
115
assert locls [k ] == v
105
116
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
+
106
137
107
138
def test_lazy_attach_returns_copies ():
108
139
_get , _dir , _all = lazy .attach (
@@ -127,18 +158,24 @@ def test_lazy_attach_returns_copies():
127
158
assert _all == [* expected , "modify_returned_all" ]
128
159
129
160
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"
132
166
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
137
169
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 )
140
174
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 )
142
179
143
180
144
181
FAKE_STUB = """
@@ -196,6 +233,10 @@ def test_require_kwarg():
196
233
math = lazy .load ("math" , require = "somepkg >= 2.0" )
197
234
assert isinstance (math , lazy .DelayedImportErrorModule )
198
235
236
+ # Eager failure
237
+ with pytest .raises (ModuleNotFoundError ):
238
+ lazy .load ("math" , require = "somepkg >= 2.0" , error_on_import = True )
239
+
199
240
# When a module can be loaded but the version can't be checked,
200
241
# raise a ValueError
201
242
with pytest .raises (ValueError ):
0 commit comments