from test.test_importlib import abc, util machinery = util.import_importlib('importlib.machinery') import os.path import unittest from test.support import import_helper, REPO_ROOT, STDLIB_DIR def resolve_stdlib_file(name, ispkg=False): assert name if ispkg: return os.path.join(STDLIB_DIR, *name.split('.'), '__init__.py') else: return os.path.join(STDLIB_DIR, *name.split('.')) + '.py' class FindSpecTests(abc.FinderTests): """Test finding frozen modules.""" def find(self, name, **kwargs): finder = self.machinery.FrozenImporter with import_helper.frozen_modules(): return finder.find_spec(name, **kwargs) def check_basic(self, spec, name, ispkg=False): self.assertEqual(spec.name, name) self.assertIs(spec.loader, self.machinery.FrozenImporter) self.assertEqual(spec.origin, 'frozen') self.assertFalse(spec.has_location) if ispkg: self.assertIsNotNone(spec.submodule_search_locations) else: self.assertIsNone(spec.submodule_search_locations) self.assertIsNotNone(spec.loader_state) def check_loader_state(self, spec, origname=None, filename=None): if not filename: if not origname: origname = spec.name filename = resolve_stdlib_file(origname) actual = dict(vars(spec.loader_state)) # Check the rest of spec.loader_state. expected = dict( origname=origname, filename=filename if origname else None, ) self.assertDictEqual(actual, expected) def check_search_locations(self, spec): """This is only called when testing packages.""" missing = object() filename = getattr(spec.loader_state, 'filename', missing) origname = getattr(spec.loader_state, 'origname', None) if not origname or filename is missing: # We deal with this in check_loader_state(). return if not filename: expected = [] elif origname != spec.name and not origname.startswith('<'): expected = [] else: expected = [os.path.dirname(filename)] self.assertListEqual(spec.submodule_search_locations, expected) def test_module(self): modules = [ '__hello__', '__phello__.spam', '__phello__.ham.eggs', ] for name in modules: with self.subTest(f'{name} -> {name}'): spec = self.find(name) self.check_basic(spec, name) self.check_loader_state(spec) modules = { '__hello_alias__': '__hello__', '_frozen_importlib': 'importlib._bootstrap', } for name, origname in modules.items(): with self.subTest(f'{name} -> {origname}'): spec = self.find(name) self.check_basic(spec, name) self.check_loader_state(spec, origname) modules = [ '__phello__.__init__', '__phello__.ham.__init__', ] for name in modules: origname = '<' + name.rpartition('.')[0] filename = resolve_stdlib_file(name) with self.subTest(f'{name} -> {origname}'): spec = self.find(name) self.check_basic(spec, name) self.check_loader_state(spec, origname, filename) modules = { '__hello_only__': ('Tools', 'freeze', 'flag.py'), } for name, path in modules.items(): origname = None filename = os.path.join(REPO_ROOT, *path) with self.subTest(f'{name} -> {filename}'): spec = self.find(name) self.check_basic(spec, name) self.check_loader_state(spec, origname, filename) def test_package(self): packages = [ '__phello__', '__phello__.ham', ] for name in packages: filename = resolve_stdlib_file(name, ispkg=True) with self.subTest(f'{name} -> {name}'): spec = self.find(name) self.check_basic(spec, name, ispkg=True) self.check_loader_state(spec, name, filename) self.check_search_locations(spec) packages = { '__phello_alias__': '__hello__', } for name, origname in packages.items(): filename = resolve_stdlib_file(origname, ispkg=False) with self.subTest(f'{name} -> {origname}'): spec = self.find(name) self.check_basic(spec, name, ispkg=True) self.check_loader_state(spec, origname, filename) self.check_search_locations(spec) # These are covered by test_module() and test_package(). test_module_in_package = None test_package_in_package = None # No easy way to test. test_package_over_module = None def test_path_ignored(self): for name in ('__hello__', '__phello__', '__phello__.spam'): actual = self.find(name) for path in (None, object(), '', 'eggs', [], [''], ['eggs']): with self.subTest((name, path)): spec = self.find(name, path=path) self.assertEqual(spec, actual) def test_target_ignored(self): imported = ('__hello__', '__phello__') with import_helper.CleanImport(*imported, usefrozen=True): import __hello__ as match import __phello__ as nonmatch name = '__hello__' actual = self.find(name) for target in (None, match, nonmatch, object(), 'not-a-module-object'): with self.subTest(target): spec = self.find(name, target=target) self.assertEqual(spec, actual) def test_failure(self): spec = self.find('') self.assertIsNone(spec) def test_not_using_frozen(self): finder = self.machinery.FrozenImporter with import_helper.frozen_modules(enabled=False): # both frozen and not frozen spec1 = finder.find_spec('__hello__') # only frozen spec2 = finder.find_spec('__hello_only__') self.assertIsNone(spec1) self.assertIsNone(spec2) (Frozen_FindSpecTests, Source_FindSpecTests ) = util.test_both(FindSpecTests, machinery=machinery) if __name__ == '__main__': unittest.main()