1from .. import util 2import importlib._bootstrap 3import sys 4from types import MethodType 5import unittest 6import warnings 7 8 9class CallingOrder: 10 11 """Calls to the importers on sys.meta_path happen in order that they are 12 specified in the sequence, starting with the first importer 13 [first called], and then continuing on down until one is found that doesn't 14 return None [continuing].""" 15 16 17 def test_first_called(self): 18 # [first called] 19 mod = 'top_level' 20 with util.mock_spec(mod) as first, util.mock_spec(mod) as second: 21 with util.import_state(meta_path=[first, second]): 22 self.assertIs(self.__import__(mod), first.modules[mod]) 23 24 def test_continuing(self): 25 # [continuing] 26 mod_name = 'for_real' 27 with util.mock_spec('nonexistent') as first, \ 28 util.mock_spec(mod_name) as second: 29 first.find_spec = lambda self, fullname, path=None, parent=None: None 30 with util.import_state(meta_path=[first, second]): 31 self.assertIs(self.__import__(mod_name), second.modules[mod_name]) 32 33 def test_empty(self): 34 # Raise an ImportWarning if sys.meta_path is empty. 35 module_name = 'nothing' 36 try: 37 del sys.modules[module_name] 38 except KeyError: 39 pass 40 with util.import_state(meta_path=[]): 41 with warnings.catch_warnings(record=True) as w: 42 warnings.simplefilter('always') 43 self.assertIsNone(importlib._bootstrap._find_spec('nothing', 44 None)) 45 self.assertEqual(len(w), 1) 46 self.assertTrue(issubclass(w[-1].category, ImportWarning)) 47 48 49(Frozen_CallingOrder, 50 Source_CallingOrder 51 ) = util.test_both(CallingOrder, __import__=util.__import__) 52 53 54class CallSignature: 55 56 """If there is no __path__ entry on the parent module, then 'path' is None 57 [no path]. Otherwise, the value for __path__ is passed in for the 'path' 58 argument [path set].""" 59 60 def log_finder(self, importer): 61 fxn = getattr(importer, self.finder_name) 62 log = [] 63 def wrapper(self, *args, **kwargs): 64 log.append([args, kwargs]) 65 return fxn(*args, **kwargs) 66 return log, wrapper 67 68 def test_no_path(self): 69 # [no path] 70 mod_name = 'top_level' 71 assert '.' not in mod_name 72 with self.mock_modules(mod_name) as importer: 73 log, wrapped_call = self.log_finder(importer) 74 setattr(importer, self.finder_name, MethodType(wrapped_call, importer)) 75 with util.import_state(meta_path=[importer]): 76 self.__import__(mod_name) 77 assert len(log) == 1 78 args = log[0][0] 79 # Assuming all arguments are positional. 80 self.assertEqual(args[0], mod_name) 81 self.assertIsNone(args[1]) 82 83 def test_with_path(self): 84 # [path set] 85 pkg_name = 'pkg' 86 mod_name = pkg_name + '.module' 87 path = [42] 88 assert '.' in mod_name 89 with self.mock_modules(pkg_name+'.__init__', mod_name) as importer: 90 importer.modules[pkg_name].__path__ = path 91 log, wrapped_call = self.log_finder(importer) 92 setattr(importer, self.finder_name, MethodType(wrapped_call, importer)) 93 with util.import_state(meta_path=[importer]): 94 self.__import__(mod_name) 95 assert len(log) == 2 96 args = log[1][0] 97 kwargs = log[1][1] 98 # Assuming all arguments are positional. 99 self.assertFalse(kwargs) 100 self.assertEqual(args[0], mod_name) 101 self.assertIs(args[1], path) 102 103class CallSignoreSuppressImportWarning(CallSignature): 104 105 def test_no_path(self): 106 with warnings.catch_warnings(): 107 warnings.simplefilter("ignore", ImportWarning) 108 super().test_no_path() 109 110 def test_with_path(self): 111 with warnings.catch_warnings(): 112 warnings.simplefilter("ignore", ImportWarning) 113 super().test_no_path() 114 115 116class CallSignaturePEP302(CallSignoreSuppressImportWarning): 117 mock_modules = util.mock_modules 118 finder_name = 'find_module' 119 120 121(Frozen_CallSignaturePEP302, 122 Source_CallSignaturePEP302 123 ) = util.test_both(CallSignaturePEP302, __import__=util.__import__) 124 125 126class CallSignaturePEP451(CallSignature): 127 mock_modules = util.mock_spec 128 finder_name = 'find_spec' 129 130 131(Frozen_CallSignaturePEP451, 132 Source_CallSignaturePEP451 133 ) = util.test_both(CallSignaturePEP451, __import__=util.__import__) 134 135 136if __name__ == '__main__': 137 unittest.main() 138