1from test.test_importlib import abc, util 2 3machinery = util.import_importlib('importlib.machinery') 4 5from test.support import captured_stdout, import_helper, STDLIB_DIR 6import contextlib 7import os.path 8import types 9import unittest 10import warnings 11 12 13@contextlib.contextmanager 14def deprecated(): 15 with warnings.catch_warnings(): 16 warnings.simplefilter('ignore', DeprecationWarning) 17 yield 18 19 20@contextlib.contextmanager 21def fresh(name, *, oldapi=False): 22 with util.uncache(name): 23 with import_helper.frozen_modules(): 24 if oldapi: 25 with deprecated(): 26 yield 27 else: 28 yield 29 30 31def resolve_stdlib_file(name, ispkg=False): 32 assert name 33 if ispkg: 34 return os.path.join(STDLIB_DIR, *name.split('.'), '__init__.py') 35 else: 36 return os.path.join(STDLIB_DIR, *name.split('.')) + '.py' 37 38 39class ExecModuleTests(abc.LoaderTests): 40 41 def exec_module(self, name, origname=None): 42 with import_helper.frozen_modules(): 43 is_package = self.machinery.FrozenImporter.is_package(name) 44 spec = self.machinery.ModuleSpec( 45 name, 46 self.machinery.FrozenImporter, 47 origin='frozen', 48 is_package=is_package, 49 loader_state=types.SimpleNamespace( 50 origname=origname or name, 51 filename=resolve_stdlib_file(origname or name, is_package), 52 ), 53 ) 54 module = types.ModuleType(name) 55 module.__spec__ = spec 56 assert not hasattr(module, 'initialized') 57 58 with fresh(name): 59 self.machinery.FrozenImporter.exec_module(module) 60 with captured_stdout() as stdout: 61 module.main() 62 63 self.assertTrue(module.initialized) 64 self.assertTrue(hasattr(module, '__spec__')) 65 self.assertEqual(module.__spec__.origin, 'frozen') 66 return module, stdout.getvalue() 67 68 def test_module(self): 69 name = '__hello__' 70 module, output = self.exec_module(name) 71 check = {'__name__': name} 72 for attr, value in check.items(): 73 self.assertEqual(getattr(module, attr), value) 74 self.assertEqual(output, 'Hello world!\n') 75 self.assertTrue(hasattr(module, '__spec__')) 76 self.assertEqual(module.__spec__.loader_state.origname, name) 77 78 def test_package(self): 79 name = '__phello__' 80 module, output = self.exec_module(name) 81 check = {'__name__': name} 82 for attr, value in check.items(): 83 attr_value = getattr(module, attr) 84 self.assertEqual(attr_value, value, 85 'for {name}.{attr}, {given!r} != {expected!r}'.format( 86 name=name, attr=attr, given=attr_value, 87 expected=value)) 88 self.assertEqual(output, 'Hello world!\n') 89 self.assertEqual(module.__spec__.loader_state.origname, name) 90 91 def test_lacking_parent(self): 92 name = '__phello__.spam' 93 with util.uncache('__phello__'): 94 module, output = self.exec_module(name) 95 check = {'__name__': name} 96 for attr, value in check.items(): 97 attr_value = getattr(module, attr) 98 self.assertEqual(attr_value, value, 99 'for {name}.{attr}, {given} != {expected!r}'.format( 100 name=name, attr=attr, given=attr_value, 101 expected=value)) 102 self.assertEqual(output, 'Hello world!\n') 103 104 def test_module_repr_indirect_through_spec(self): 105 name = '__hello__' 106 module, output = self.exec_module(name) 107 self.assertEqual(repr(module), 108 "<module '__hello__' (frozen)>") 109 110 # No way to trigger an error in a frozen module. 111 test_state_after_failure = None 112 113 def test_unloadable(self): 114 with import_helper.frozen_modules(): 115 assert self.machinery.FrozenImporter.find_spec('_not_real') is None 116 with self.assertRaises(ImportError) as cm: 117 self.exec_module('_not_real') 118 self.assertEqual(cm.exception.name, '_not_real') 119 120 121(Frozen_ExecModuleTests, 122 Source_ExecModuleTests 123 ) = util.test_both(ExecModuleTests, machinery=machinery) 124 125 126class InspectLoaderTests: 127 128 """Tests for the InspectLoader methods for FrozenImporter.""" 129 130 def test_get_code(self): 131 # Make sure that the code object is good. 132 name = '__hello__' 133 with import_helper.frozen_modules(): 134 code = self.machinery.FrozenImporter.get_code(name) 135 mod = types.ModuleType(name) 136 exec(code, mod.__dict__) 137 with captured_stdout() as stdout: 138 mod.main() 139 self.assertTrue(hasattr(mod, 'initialized')) 140 self.assertEqual(stdout.getvalue(), 'Hello world!\n') 141 142 def test_get_source(self): 143 # Should always return None. 144 with import_helper.frozen_modules(): 145 result = self.machinery.FrozenImporter.get_source('__hello__') 146 self.assertIsNone(result) 147 148 def test_is_package(self): 149 # Should be able to tell what is a package. 150 test_for = (('__hello__', False), ('__phello__', True), 151 ('__phello__.spam', False)) 152 for name, is_package in test_for: 153 with import_helper.frozen_modules(): 154 result = self.machinery.FrozenImporter.is_package(name) 155 self.assertEqual(bool(result), is_package) 156 157 def test_failure(self): 158 # Raise ImportError for modules that are not frozen. 159 for meth_name in ('get_code', 'get_source', 'is_package'): 160 method = getattr(self.machinery.FrozenImporter, meth_name) 161 with self.assertRaises(ImportError) as cm: 162 with import_helper.frozen_modules(): 163 method('importlib') 164 self.assertEqual(cm.exception.name, 'importlib') 165 166(Frozen_ILTests, 167 Source_ILTests 168 ) = util.test_both(InspectLoaderTests, machinery=machinery) 169 170 171if __name__ == '__main__': 172 unittest.main() 173