3
frozen_init, source_init = util.import_importlib('importlib')
4
frozen_util, source_util = util.import_importlib('importlib.util')
5
frozen_machinery, source_machinery = util.import_importlib('importlib.machinery')
9
from test import support
14
class ImportModuleTests:
16
"""Test importlib.import_module."""
18
def test_module_import(self):
19
# Test importing a top-level module.
20
with util.mock_modules('top_level') as mock:
21
with util.import_state(meta_path=[mock]):
22
module = self.init.import_module('top_level')
23
self.assertEqual(module.__name__, 'top_level')
25
def test_absolute_package_import(self):
26
# Test importing a module from a package with an absolute name.
28
pkg_long_name = '{0}.__init__'.format(pkg_name)
29
name = '{0}.mod'.format(pkg_name)
30
with util.mock_modules(pkg_long_name, name) as mock:
31
with util.import_state(meta_path=[mock]):
32
module = self.init.import_module(name)
33
self.assertEqual(module.__name__, name)
35
def test_shallow_relative_package_import(self):
36
# Test importing a module from a package through a relative import.
38
pkg_long_name = '{0}.__init__'.format(pkg_name)
40
absolute_name = '{0}.{1}'.format(pkg_name, module_name)
41
relative_name = '.{0}'.format(module_name)
42
with util.mock_modules(pkg_long_name, absolute_name) as mock:
43
with util.import_state(meta_path=[mock]):
44
self.init.import_module(pkg_name)
45
module = self.init.import_module(relative_name, pkg_name)
46
self.assertEqual(module.__name__, absolute_name)
48
def test_deep_relative_package_import(self):
49
modules = ['a.__init__', 'a.b.__init__', 'a.c']
50
with util.mock_modules(*modules) as mock:
51
with util.import_state(meta_path=[mock]):
52
self.init.import_module('a')
53
self.init.import_module('a.b')
54
module = self.init.import_module('..c', 'a.b')
55
self.assertEqual(module.__name__, 'a.c')
57
def test_absolute_import_with_package(self):
58
# Test importing a module from a package with an absolute name with
59
# the 'package' argument given.
61
pkg_long_name = '{0}.__init__'.format(pkg_name)
62
name = '{0}.mod'.format(pkg_name)
63
with util.mock_modules(pkg_long_name, name) as mock:
64
with util.import_state(meta_path=[mock]):
65
self.init.import_module(pkg_name)
66
module = self.init.import_module(name, pkg_name)
67
self.assertEqual(module.__name__, name)
69
def test_relative_import_wo_package(self):
70
# Relative imports cannot happen without the 'package' argument being
72
with self.assertRaises(TypeError):
73
self.init.import_module('.support')
76
def test_loaded_once(self):
77
# Issue #13591: Modules should only be loaded once when
78
# initializing the parent package attempts to import the
79
# module currently being imported.
82
self.init.import_module('a.b')
86
code = {'a': load_a, 'a.b': load_b}
87
modules = ['a.__init__', 'a.b']
88
with util.mock_modules(*modules, module_code=code) as mock:
89
with util.import_state(meta_path=[mock]):
90
self.init.import_module('a.b')
91
self.assertEqual(b_load_count, 1)
93
class Frozen_ImportModuleTests(ImportModuleTests, unittest.TestCase):
96
class Source_ImportModuleTests(ImportModuleTests, unittest.TestCase):
100
class FindLoaderTests:
102
class FakeMetaFinder:
104
def find_module(name, path=None): return name, path
106
def test_sys_modules(self):
107
# If a module with __loader__ is in sys.modules, then return it.
109
with util.uncache(name):
110
module = types.ModuleType(name)
112
module.__loader__ = loader
113
sys.modules[name] = module
114
found = self.init.find_loader(name)
115
self.assertEqual(loader, found)
117
def test_sys_modules_loader_is_None(self):
118
# If sys.modules[name].__loader__ is None, raise ValueError.
120
with util.uncache(name):
121
module = types.ModuleType(name)
122
module.__loader__ = None
123
sys.modules[name] = module
124
with self.assertRaises(ValueError):
125
self.init.find_loader(name)
127
def test_sys_modules_loader_is_not_set(self):
128
# Should raise ValueError
131
with util.uncache(name):
132
module = types.ModuleType(name)
134
del module.__loader__
135
except AttributeError:
137
sys.modules[name] = module
138
with self.assertRaises(ValueError):
139
self.init.find_loader(name)
141
def test_success(self):
142
# Return the loader found on sys.meta_path.
144
with util.uncache(name):
145
with util.import_state(meta_path=[self.FakeMetaFinder]):
146
self.assertEqual((name, None), self.init.find_loader(name))
148
def test_success_path(self):
149
# Searching on a path should work.
151
path = 'path to some place'
152
with util.uncache(name):
153
with util.import_state(meta_path=[self.FakeMetaFinder]):
154
self.assertEqual((name, path),
155
self.init.find_loader(name, path))
157
def test_nothing(self):
158
# None is returned upon failure to find a loader.
159
self.assertIsNone(self.init.find_loader('nevergoingtofindthismodule'))
161
class Frozen_FindLoaderTests(FindLoaderTests, unittest.TestCase):
164
class Source_FindLoaderTests(FindLoaderTests, unittest.TestCase):
170
class FakeMetaFinder:
172
def find_spec(name, path=None, target=None): return name, path, target
174
def test_sys_modules(self):
176
with util.uncache(name):
177
module = types.ModuleType(name)
179
spec = self.machinery.ModuleSpec(name, loader)
180
module.__loader__ = loader
181
module.__spec__ = spec
182
sys.modules[name] = module
183
found = self.init.find_spec(name)
184
self.assertEqual(found, spec)
186
def test_sys_modules_without___loader__(self):
188
with util.uncache(name):
189
module = types.ModuleType(name)
190
del module.__loader__
192
spec = self.machinery.ModuleSpec(name, loader)
193
module.__spec__ = spec
194
sys.modules[name] = module
195
found = self.init.find_spec(name)
196
self.assertEqual(found, spec)
198
def test_sys_modules_spec_is_None(self):
200
with util.uncache(name):
201
module = types.ModuleType(name)
202
module.__spec__ = None
203
sys.modules[name] = module
204
with self.assertRaises(ValueError):
205
self.init.find_spec(name)
207
def test_sys_modules_loader_is_None(self):
209
with util.uncache(name):
210
module = types.ModuleType(name)
211
spec = self.machinery.ModuleSpec(name, None)
212
module.__spec__ = spec
213
sys.modules[name] = module
214
found = self.init.find_spec(name)
215
self.assertEqual(found, spec)
217
def test_sys_modules_spec_is_not_set(self):
219
with util.uncache(name):
220
module = types.ModuleType(name)
223
except AttributeError:
225
sys.modules[name] = module
226
with self.assertRaises(ValueError):
227
self.init.find_spec(name)
229
def test_success(self):
231
with util.uncache(name):
232
with util.import_state(meta_path=[self.FakeMetaFinder]):
233
self.assertEqual((name, None, None),
234
self.init.find_spec(name))
236
def test_success_path(self):
237
# Searching on a path should work.
239
path = 'path to some place'
240
with util.uncache(name):
241
with util.import_state(meta_path=[self.FakeMetaFinder]):
242
self.assertEqual((name, path, None),
243
self.init.find_spec(name, path))
245
def test_nothing(self):
246
# None is returned upon failure to find a loader.
247
self.assertIsNone(self.init.find_spec('nevergoingtofindthismodule'))
249
class Frozen_FindSpecTests(FindSpecTests, unittest.TestCase):
251
machinery = frozen_machinery
253
class Source_FindSpecTests(FindSpecTests, unittest.TestCase):
255
machinery = source_machinery
260
"""Test module reloading for builtin and extension modules."""
262
def test_reload_modules(self):
263
for mod in ('tokenize', 'time', 'marshal'):
264
with self.subTest(module=mod):
265
with support.CleanImport(mod):
266
module = self.init.import_module(mod)
267
self.init.reload(module)
269
def test_module_replaced(self):
272
module = type(sys)('top_level')
274
sys.modules['top_level'] = module
275
mock = util.mock_modules('top_level',
276
module_code={'top_level': code})
278
with util.import_state(meta_path=[mock]):
279
module = self.init.import_module('top_level')
280
reloaded = self.init.reload(module)
281
actual = sys.modules['top_level']
282
self.assertEqual(actual.spam, 3)
283
self.assertEqual(reloaded.spam, 3)
285
def test_reload_missing_loader(self):
286
with support.CleanImport('types'):
288
loader = types.__loader__
290
reloaded = self.init.reload(types)
292
self.assertIs(reloaded, types)
293
self.assertIs(sys.modules['types'], types)
294
self.assertEqual(reloaded.__loader__.path, loader.path)
296
def test_reload_loader_replaced(self):
297
with support.CleanImport('types'):
299
types.__loader__ = None
300
self.init.invalidate_caches()
301
reloaded = self.init.reload(types)
303
self.assertIsNot(reloaded.__loader__, None)
304
self.assertIs(reloaded, types)
305
self.assertIs(sys.modules['types'], types)
307
def test_reload_location_changed(self):
309
with support.temp_cwd(None) as cwd:
310
with util.uncache('spam'):
311
with support.DirsOnSysPath(cwd):
312
# Start as a plain module.
313
self.init.invalidate_caches()
314
path = os.path.join(cwd, name + '.py')
315
cached = self.util.cache_from_source(path)
316
expected = {'__name__': name,
319
'__cached__': cached,
321
'__builtins__': __builtins__,
323
support.create_empty_file(path)
324
module = self.init.import_module(name)
326
loader = ns.pop('__loader__')
327
spec = ns.pop('__spec__')
328
self.assertEqual(spec.name, name)
329
self.assertEqual(spec.loader, loader)
330
self.assertEqual(loader.path, path)
331
self.assertEqual(ns, expected)
333
# Change to a package.
334
self.init.invalidate_caches()
335
init_path = os.path.join(cwd, name, '__init__.py')
336
cached = self.util.cache_from_source(init_path)
337
expected = {'__name__': name,
339
'__file__': init_path,
340
'__cached__': cached,
341
'__path__': [os.path.dirname(init_path)],
343
'__builtins__': __builtins__,
346
os.rename(path, init_path)
347
reloaded = self.init.reload(module)
349
loader = ns.pop('__loader__')
350
spec = ns.pop('__spec__')
351
self.assertEqual(spec.name, name)
352
self.assertEqual(spec.loader, loader)
353
self.assertIs(reloaded, module)
354
self.assertEqual(loader.path, init_path)
356
self.assertEqual(ns, expected)
358
def test_reload_namespace_changed(self):
360
with support.temp_cwd(None) as cwd:
361
with util.uncache('spam'):
362
with support.DirsOnSysPath(cwd):
363
# Start as a namespace package.
364
self.init.invalidate_caches()
365
bad_path = os.path.join(cwd, name, '__init.py')
366
cached = self.util.cache_from_source(bad_path)
367
expected = {'__name__': name,
372
with open(bad_path, 'w') as init_file:
373
init_file.write('eggs = None')
374
module = self.init.import_module(name)
376
loader = ns.pop('__loader__')
377
path = ns.pop('__path__')
378
spec = ns.pop('__spec__')
379
self.assertEqual(spec.name, name)
380
self.assertIs(spec.loader, None)
381
self.assertIsNot(loader, None)
382
self.assertEqual(set(path),
383
set([os.path.dirname(bad_path)]))
384
with self.assertRaises(AttributeError):
387
self.assertEqual(ns, expected)
389
# Change to a regular package.
390
self.init.invalidate_caches()
391
init_path = os.path.join(cwd, name, '__init__.py')
392
cached = self.util.cache_from_source(init_path)
393
expected = {'__name__': name,
395
'__file__': init_path,
396
'__cached__': cached,
397
'__path__': [os.path.dirname(init_path)],
399
'__builtins__': __builtins__,
402
os.rename(bad_path, init_path)
403
reloaded = self.init.reload(module)
405
loader = ns.pop('__loader__')
406
spec = ns.pop('__spec__')
407
self.assertEqual(spec.name, name)
408
self.assertEqual(spec.loader, loader)
409
self.assertIs(reloaded, module)
410
self.assertEqual(loader.path, init_path)
411
self.assertEqual(ns, expected)
414
class Frozen_ReloadTests(ReloadTests, unittest.TestCase):
418
class Source_ReloadTests(ReloadTests, unittest.TestCase):
423
class InvalidateCacheTests:
425
def test_method_called(self):
426
# If defined the method should be called.
427
class InvalidatingNullFinder:
428
def __init__(self, *ignored):
430
def find_module(self, *args):
432
def invalidate_caches(self):
436
meta_ins = InvalidatingNullFinder()
437
path_ins = InvalidatingNullFinder()
438
sys.meta_path.insert(0, meta_ins)
439
self.addCleanup(lambda: sys.path_importer_cache.__delitem__(key))
440
sys.path_importer_cache[key] = path_ins
441
self.addCleanup(lambda: sys.meta_path.remove(meta_ins))
442
self.init.invalidate_caches()
443
self.assertTrue(meta_ins.called)
444
self.assertTrue(path_ins.called)
446
def test_method_lacking(self):
447
# There should be no issues if the method is not defined.
448
key = 'gobbledeegook'
449
sys.path_importer_cache[key] = None
450
self.addCleanup(lambda: sys.path_importer_cache.__delitem__(key))
451
self.init.invalidate_caches() # Shouldn't trigger an exception.
453
class Frozen_InvalidateCacheTests(InvalidateCacheTests, unittest.TestCase):
456
class Source_InvalidateCacheTests(InvalidateCacheTests, unittest.TestCase):
460
class FrozenImportlibTests(unittest.TestCase):
462
def test_no_frozen_importlib(self):
463
# Should be able to import w/o _frozen_importlib being defined.
464
# Can't do an isinstance() check since separate copies of importlib
465
# may have been used for import, so just check the name is not for the
467
self.assertNotEqual(source_init.__loader__.__class__.__name__,
473
def test_everyone_has___loader__(self):
474
# Issue #17098: all modules should have __loader__ defined.
475
for name, module in sys.modules.items():
476
if isinstance(module, types.ModuleType):
477
with self.subTest(name=name):
478
self.assertTrue(hasattr(module, '__loader__'),
479
'{!r} lacks a __loader__ attribute'.format(name))
480
if self.machinery.BuiltinImporter.find_module(name):
481
self.assertIsNot(module.__loader__, None)
482
elif self.machinery.FrozenImporter.find_module(name):
483
self.assertIsNot(module.__loader__, None)
485
def test_everyone_has___spec__(self):
486
for name, module in sys.modules.items():
487
if isinstance(module, types.ModuleType):
488
with self.subTest(name=name):
489
self.assertTrue(hasattr(module, '__spec__'))
490
if self.machinery.BuiltinImporter.find_module(name):
491
self.assertIsNot(module.__spec__, None)
492
elif self.machinery.FrozenImporter.find_module(name):
493
self.assertIsNot(module.__spec__, None)
495
class Frozen_StartupTests(StartupTests, unittest.TestCase):
496
machinery = frozen_machinery
498
class Source_StartupTests(StartupTests, unittest.TestCase):
499
machinery = source_machinery
502
if __name__ == '__main__':