1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
import importlib
import sys
import types
import pytest
import networkx.lazy_imports as lazy
def test_lazy_import_basics():
math = lazy._lazy_import("math")
anything_not_real = lazy._lazy_import("anything_not_real")
# Now test that accessing attributes does what it should
assert math.sin(math.pi) == pytest.approx(0, 1e-6)
# poor-mans pytest.raises for testing errors on attribute access
try:
anything_not_real.pi
assert False # Should not get here
except ModuleNotFoundError:
pass
assert isinstance(anything_not_real, lazy.DelayedImportErrorModule)
# see if it changes for second access
try:
anything_not_real.pi
assert False # Should not get here
except ModuleNotFoundError:
pass
def test_lazy_import_impact_on_sys_modules():
math = lazy._lazy_import("math")
anything_not_real = lazy._lazy_import("anything_not_real")
assert type(math) == types.ModuleType
assert "math" in sys.modules
assert type(anything_not_real) == lazy.DelayedImportErrorModule
assert "anything_not_real" not in sys.modules
# only do this if numpy is installed
np_test = pytest.importorskip("numpy")
np = lazy._lazy_import("numpy")
assert type(np) == types.ModuleType
assert "numpy" in sys.modules
np.pi # trigger load of numpy
assert type(np) == types.ModuleType
assert "numpy" in sys.modules
def test_lazy_import_nonbuiltins():
sp = lazy._lazy_import("scipy")
np = lazy._lazy_import("numpy")
if isinstance(sp, lazy.DelayedImportErrorModule):
try:
sp.special.erf
assert False
except ModuleNotFoundError:
pass
elif isinstance(np, lazy.DelayedImportErrorModule):
try:
np.sin(np.pi)
assert False
except ModuleNotFoundError:
pass
else:
assert sp.special.erf(np.pi) == pytest.approx(1, 1e-4)
def test_lazy_attach():
name = "mymod"
submods = ["mysubmodule", "anothersubmodule"]
myall = {"not_real_submod": ["some_var_or_func"]}
locls = {
"attach": lazy.attach,
"name": name,
"submods": submods,
"myall": myall,
}
s = "__getattr__, __lazy_dir__, __all__ = attach(name, submods, myall)"
exec(s, {}, locls)
expected = {
"attach": lazy.attach,
"name": name,
"submods": submods,
"myall": myall,
"__getattr__": None,
"__lazy_dir__": None,
"__all__": None,
}
assert locls.keys() == expected.keys()
for k, v in expected.items():
if v is not None:
assert locls[k] == v
|