test_finder.py revision d71bed3d76cc90dac24f88197bd37fdc2063330d
1f87e04d3398091662c399ee5ba0a3e71dbae9a24Brett Cannonfrom importlib import _bootstrap 2f254a75176928e1d1228a5d20d49fbe2fe9f290aBrett Cannonfrom .. import abc 34ee2cdaf65971391b35ce7aaad5ce77ddcbb176eBrett Cannonfrom . import util as source_util 428a691b7fdde1b8abafa4c4a5025e6bfa44f48b9Barry Warsawfrom test.support import make_legacy_pyc 523cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannonimport os 628a691b7fdde1b8abafa4c4a5025e6bfa44f48b9Barry Warsawimport errno 723cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannonimport py_compile 823cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannonimport unittest 923cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannonimport warnings 1023cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon 1123cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon 12f254a75176928e1d1228a5d20d49fbe2fe9f290aBrett Cannonclass FinderTests(abc.FinderTests): 1323cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon 1423cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon """For a top-level module, it should just be found directly in the 1523cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon directory being searched. This is true for a directory with source 1623cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon [top-level source], bytecode [top-level bc], or both [top-level both]. 1723cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon There is also the possibility that it is a package [top-level package], in 1823cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon which case there will be a directory with the module name and an 1923cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon __init__.py file. If there is a directory without an __init__.py an 2023cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon ImportWarning is returned [empty dir]. 2123cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon 2223cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon For sub-modules and sub-packages, the same happens as above but only use 2323cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon the tail end of the name [sub module] [sub package] [sub empty]. 2423cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon 2523cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon When there is a conflict between a package and module having the same name 2623cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon in the same directory, the package wins out [package over module]. This is 2723cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon so that imports of modules within the package can occur rather than trigger 2823cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon an import error. 2923cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon 3023cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon When there is a package and module with the same name, always pick the 3123cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon package over the module [package over module]. This is so that imports from 3223cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon the package have the possibility of succeeding. 3323cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon 3423cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon """ 3523cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon 3623cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon def import_(self, root, module): 3761b14251d3a653548f70350acb250cf23b696372Brett Cannon finder = _bootstrap._FileFinder(root, 3861b14251d3a653548f70350acb250cf23b696372Brett Cannon _bootstrap._SourceFinderDetails(), 3961b14251d3a653548f70350acb250cf23b696372Brett Cannon _bootstrap._SourcelessFinderDetails()) 4023cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon return finder.find_module(module) 4123cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon 4223cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon def run_test(self, test, create=None, *, compile_=None, unlink=None): 4323cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon """Test the finding of 'test' with the creation of modules listed in 4423cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon 'create'. 4523cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon 4623cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon Any names listed in 'compile_' are byte-compiled. Modules 4723cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon listed in 'unlink' have their source files deleted. 4823cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon 4923cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon """ 5023cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon if create is None: 5123cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon create = {test} 524ee2cdaf65971391b35ce7aaad5ce77ddcbb176eBrett Cannon with source_util.create_modules(*create) as mapping: 5323cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon if compile_: 5423cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon for name in compile_: 5523cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon py_compile.compile(mapping[name]) 5623cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon if unlink: 5723cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon for name in unlink: 5823cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon os.unlink(mapping[name]) 5928a691b7fdde1b8abafa4c4a5025e6bfa44f48b9Barry Warsaw try: 6028a691b7fdde1b8abafa4c4a5025e6bfa44f48b9Barry Warsaw make_legacy_pyc(mapping[name]) 6128a691b7fdde1b8abafa4c4a5025e6bfa44f48b9Barry Warsaw except OSError as error: 6228a691b7fdde1b8abafa4c4a5025e6bfa44f48b9Barry Warsaw # Some tests do not set compile_=True so the source 6328a691b7fdde1b8abafa4c4a5025e6bfa44f48b9Barry Warsaw # module will not get compiled and there will be no 6428a691b7fdde1b8abafa4c4a5025e6bfa44f48b9Barry Warsaw # PEP 3147 pyc file to rename. 6528a691b7fdde1b8abafa4c4a5025e6bfa44f48b9Barry Warsaw if error.errno != errno.ENOENT: 6628a691b7fdde1b8abafa4c4a5025e6bfa44f48b9Barry Warsaw raise 6723cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon loader = self.import_(mapping['.root'], test) 68c9c0f201fed21efcf669dbbf5f923eaf0eeb1db9Benjamin Peterson self.assertTrue(hasattr(loader, 'load_module')) 6923cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon return loader 7023cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon 7123cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon def test_module(self): 7223cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon # [top-level source] 7323cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon self.run_test('top_level') 7423cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon # [top-level bc] 7528a691b7fdde1b8abafa4c4a5025e6bfa44f48b9Barry Warsaw self.run_test('top_level', compile_={'top_level'}, 7628a691b7fdde1b8abafa4c4a5025e6bfa44f48b9Barry Warsaw unlink={'top_level'}) 7723cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon # [top-level both] 7823cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon self.run_test('top_level', compile_={'top_level'}) 7923cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon 8023cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon # [top-level package] 8123cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon def test_package(self): 8223cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon # Source. 8323cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon self.run_test('pkg', {'pkg.__init__'}) 8423cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon # Bytecode. 8523cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon self.run_test('pkg', {'pkg.__init__'}, compile_={'pkg.__init__'}, 8623cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon unlink={'pkg.__init__'}) 8723cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon # Both. 8823cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon self.run_test('pkg', {'pkg.__init__'}, compile_={'pkg.__init__'}) 8923cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon 9023cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon # [sub module] 9123cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon def test_module_in_package(self): 924ee2cdaf65971391b35ce7aaad5ce77ddcbb176eBrett Cannon with source_util.create_modules('pkg.__init__', 'pkg.sub') as mapping: 9323cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon pkg_dir = os.path.dirname(mapping['pkg.__init__']) 9423cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon loader = self.import_(pkg_dir, 'pkg.sub') 95c9c0f201fed21efcf669dbbf5f923eaf0eeb1db9Benjamin Peterson self.assertTrue(hasattr(loader, 'load_module')) 9623cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon 9723cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon # [sub package] 9823cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon def test_package_in_package(self): 994ee2cdaf65971391b35ce7aaad5ce77ddcbb176eBrett Cannon context = source_util.create_modules('pkg.__init__', 'pkg.sub.__init__') 10023cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon with context as mapping: 10123cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon pkg_dir = os.path.dirname(mapping['pkg.__init__']) 10223cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon loader = self.import_(pkg_dir, 'pkg.sub') 103c9c0f201fed21efcf669dbbf5f923eaf0eeb1db9Benjamin Peterson self.assertTrue(hasattr(loader, 'load_module')) 10423cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon 10523cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon # [sub empty] 10623cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon def test_empty_sub_directory(self): 1074ee2cdaf65971391b35ce7aaad5ce77ddcbb176eBrett Cannon context = source_util.create_modules('pkg.__init__', 'pkg.sub.__init__') 10823cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon with warnings.catch_warnings(): 10923cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon warnings.simplefilter("error", ImportWarning) 11023cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon with context as mapping: 11123cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon os.unlink(mapping['pkg.sub.__init__']) 11223cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon pkg_dir = os.path.dirname(mapping['pkg.__init__']) 1132153dc001f5565592b44808d7f0f25815010eb9dBrett Cannon with self.assertRaises(ImportWarning): 1142153dc001f5565592b44808d7f0f25815010eb9dBrett Cannon self.import_(pkg_dir, 'pkg.sub') 11523cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon 11623cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon # [package over modules] 11723cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon def test_package_over_module(self): 11823cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon name = '_temp' 11923cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon loader = self.run_test(name, {'{0}.__init__'.format(name), name}) 12061b14251d3a653548f70350acb250cf23b696372Brett Cannon self.assertTrue('__init__' in loader.get_filename(name)) 12123cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon 12223cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon 12323cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon def test_failure(self): 1244ee2cdaf65971391b35ce7aaad5ce77ddcbb176eBrett Cannon with source_util.create_modules('blah') as mapping: 12523cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon nothing = self.import_(mapping['.root'], 'sdfsadsadf') 126c9c0f201fed21efcf669dbbf5f923eaf0eeb1db9Benjamin Peterson self.assertTrue(nothing is None) 12723cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon 12823cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon # [empty dir] 12923cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon def test_empty_dir(self): 13023cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon with warnings.catch_warnings(): 13123cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon warnings.simplefilter("error", ImportWarning) 1322153dc001f5565592b44808d7f0f25815010eb9dBrett Cannon with self.assertRaises(ImportWarning): 1332153dc001f5565592b44808d7f0f25815010eb9dBrett Cannon self.run_test('pkg', {'pkg.__init__'}, unlink={'pkg.__init__'}) 13423cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon 135d71bed3d76cc90dac24f88197bd37fdc2063330dBrett Cannon def test_empty_string_for_dir(self): 136d71bed3d76cc90dac24f88197bd37fdc2063330dBrett Cannon # The empty string from sys.path means to search in the cwd. 137d71bed3d76cc90dac24f88197bd37fdc2063330dBrett Cannon finder = _bootstrap._FileFinder('', _bootstrap._SourceFinderDetails()) 138d71bed3d76cc90dac24f88197bd37fdc2063330dBrett Cannon with open('mod.py', 'w') as file: 139d71bed3d76cc90dac24f88197bd37fdc2063330dBrett Cannon file.write("# test file for importlib") 140d71bed3d76cc90dac24f88197bd37fdc2063330dBrett Cannon try: 141d71bed3d76cc90dac24f88197bd37fdc2063330dBrett Cannon loader = finder.find_module('mod') 142d71bed3d76cc90dac24f88197bd37fdc2063330dBrett Cannon self.assertTrue(hasattr(loader, 'load_module')) 143d71bed3d76cc90dac24f88197bd37fdc2063330dBrett Cannon finally: 144d71bed3d76cc90dac24f88197bd37fdc2063330dBrett Cannon os.unlink('mod.py') 145d71bed3d76cc90dac24f88197bd37fdc2063330dBrett Cannon 14623cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon 14723cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannondef test_main(): 14823cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon from test.support import run_unittest 14923cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon run_unittest(FinderTests) 15023cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon 15123cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon 15223cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannonif __name__ == '__main__': 15323cbd8a6564df0ac3df339f91196c45f3e626d32Brett Cannon test_main() 154