13
13
from test .support .script_helper import assert_python_failure
14
14
15
15
16
- class LoaderTests ( abc . LoaderTests ) :
16
+ class LoaderTests :
17
17
18
- """Test load_module() for extension modules ."""
18
+ """Test ExtensionFileLoader ."""
19
19
20
20
def setUp (self ):
21
21
if not self .machinery .EXTENSION_SUFFIXES :
@@ -32,15 +32,6 @@ def load_module(self, fullname):
32
32
warnings .simplefilter ("ignore" , DeprecationWarning )
33
33
return self .loader .load_module (fullname )
34
34
35
- def test_load_module_API (self ):
36
- # Test the default argument for load_module().
37
- with warnings .catch_warnings ():
38
- warnings .simplefilter ("ignore" , DeprecationWarning )
39
- self .loader .load_module ()
40
- self .loader .load_module (None )
41
- with self .assertRaises (ImportError ):
42
- self .load_module ('XXX' )
43
-
44
35
def test_equality (self ):
45
36
other = self .machinery .ExtensionFileLoader (util .EXTENSIONS .name ,
46
37
util .EXTENSIONS .file_path )
@@ -51,6 +42,15 @@ def test_inequality(self):
51
42
util .EXTENSIONS .file_path )
52
43
self .assertNotEqual (self .loader , other )
53
44
45
+ def test_load_module_API (self ):
46
+ # Test the default argument for load_module().
47
+ with warnings .catch_warnings ():
48
+ warnings .simplefilter ("ignore" , DeprecationWarning )
49
+ self .loader .load_module ()
50
+ self .loader .load_module (None )
51
+ with self .assertRaises (ImportError ):
52
+ self .load_module ('XXX' )
53
+
54
54
def test_module (self ):
55
55
with util .uncache (util .EXTENSIONS .name ):
56
56
module = self .load_module (util .EXTENSIONS .name )
@@ -68,12 +68,6 @@ def test_module(self):
68
68
# No extension module in a package available for testing.
69
69
test_lacking_parent = None
70
70
71
- def test_module_reuse (self ):
72
- with util .uncache (util .EXTENSIONS .name ):
73
- module1 = self .load_module (util .EXTENSIONS .name )
74
- module2 = self .load_module (util .EXTENSIONS .name )
75
- self .assertIs (module1 , module2 )
76
-
77
71
# No easy way to trigger a failure after a successful import.
78
72
test_state_after_failure = None
79
73
@@ -83,17 +77,106 @@ def test_unloadable(self):
83
77
self .load_module (name )
84
78
self .assertEqual (cm .exception .name , name )
85
79
80
+ def test_module_reuse (self ):
81
+ with util .uncache (util .EXTENSIONS .name ):
82
+ module1 = self .load_module (util .EXTENSIONS .name )
83
+ module2 = self .load_module (util .EXTENSIONS .name )
84
+ self .assertIs (module1 , module2 )
85
+
86
86
def test_is_package (self ):
87
87
self .assertFalse (self .loader .is_package (util .EXTENSIONS .name ))
88
88
for suffix in self .machinery .EXTENSION_SUFFIXES :
89
89
path = os .path .join ('some' , 'path' , 'pkg' , '__init__' + suffix )
90
90
loader = self .machinery .ExtensionFileLoader ('pkg' , path )
91
91
self .assertTrue (loader .is_package ('pkg' ))
92
92
93
+
93
94
(Frozen_LoaderTests ,
94
95
Source_LoaderTests
95
96
) = util .test_both (LoaderTests , machinery = machinery )
96
97
98
+
99
+ class SinglePhaseExtensionModuleTests (abc .LoaderTests ):
100
+ # Test loading extension modules without multi-phase initialization.
101
+
102
+ def setUp (self ):
103
+ if not self .machinery .EXTENSION_SUFFIXES :
104
+ raise unittest .SkipTest ("Requires dynamic loading support." )
105
+ self .name = '_testsinglephase'
106
+ if self .name in sys .builtin_module_names :
107
+ raise unittest .SkipTest (
108
+ f"{ self .name } is a builtin module"
109
+ )
110
+ finder = self .machinery .FileFinder (None )
111
+ self .spec = importlib .util .find_spec (self .name )
112
+ assert self .spec
113
+ self .loader = self .machinery .ExtensionFileLoader (
114
+ self .name , self .spec .origin )
115
+
116
+ def load_module (self ):
117
+ with warnings .catch_warnings ():
118
+ warnings .simplefilter ("ignore" , DeprecationWarning )
119
+ return self .loader .load_module (self .name )
120
+
121
+ def load_module_by_name (self , fullname ):
122
+ # Load a module from the test extension by name.
123
+ origin = self .spec .origin
124
+ loader = self .machinery .ExtensionFileLoader (fullname , origin )
125
+ spec = importlib .util .spec_from_loader (fullname , loader )
126
+ module = importlib .util .module_from_spec (spec )
127
+ loader .exec_module (module )
128
+ return module
129
+
130
+ def test_module (self ):
131
+ # Test loading an extension module.
132
+ with util .uncache (self .name ):
133
+ module = self .load_module ()
134
+ for attr , value in [('__name__' , self .name ),
135
+ ('__file__' , self .spec .origin ),
136
+ ('__package__' , '' )]:
137
+ self .assertEqual (getattr (module , attr ), value )
138
+ with self .assertRaises (AttributeError ):
139
+ module .__path__
140
+ self .assertIs (module , sys .modules [self .name ])
141
+ self .assertIsInstance (module .__loader__ ,
142
+ self .machinery .ExtensionFileLoader )
143
+
144
+ # No extension module as __init__ available for testing.
145
+ test_package = None
146
+
147
+ # No extension module in a package available for testing.
148
+ test_lacking_parent = None
149
+
150
+ # No easy way to trigger a failure after a successful import.
151
+ test_state_after_failure = None
152
+
153
+ def test_unloadable (self ):
154
+ name = 'asdfjkl;'
155
+ with self .assertRaises (ImportError ) as cm :
156
+ self .load_module_by_name (name )
157
+ self .assertEqual (cm .exception .name , name )
158
+
159
+ def test_unloadable_nonascii (self ):
160
+ # Test behavior with nonexistent module with non-ASCII name.
161
+ name = 'fo\xf3 '
162
+ with self .assertRaises (ImportError ) as cm :
163
+ self .load_module_by_name (name )
164
+ self .assertEqual (cm .exception .name , name )
165
+
166
+ # It may make sense to add the equivalent to
167
+ # the following MultiPhaseExtensionModuleTests tests:
168
+ #
169
+ # * test_nonmodule
170
+ # * test_nonmodule_with_methods
171
+ # * test_bad_modules
172
+ # * test_nonascii
173
+
174
+
175
+ (Frozen_SinglePhaseExtensionModuleTests ,
176
+ Source_SinglePhaseExtensionModuleTests
177
+ ) = util .test_both (SinglePhaseExtensionModuleTests , machinery = machinery )
178
+
179
+
97
180
class MultiPhaseExtensionModuleTests (abc .LoaderTests ):
98
181
# Test loading extension modules with multi-phase initialization (PEP 489).
99
182
0 commit comments