1 from .. import util 2 3 from importlib import machinery 4 import sys 5 import types 6 import unittest 7 8 PKG_NAME = 'fine' 9 SUBMOD_NAME = 'fine.bogus' 10 11 12 class BadSpecFinderLoader: 13 @classmethod 14 def find_spec(cls, fullname, path=None, target=None): 15 if fullname == SUBMOD_NAME: 16 spec = machinery.ModuleSpec(fullname, cls) 17 return spec 18 19 @staticmethod 20 def create_module(spec): 21 return None 22 23 @staticmethod 24 def exec_module(module): 25 if module.__name__ == SUBMOD_NAME: 26 raise ImportError('I cannot be loaded!') 27 28 29 class BadLoaderFinder: 30 @classmethod 31 def find_module(cls, fullname, path): 32 if fullname == SUBMOD_NAME: 33 return cls 34 35 @classmethod 36 def load_module(cls, fullname): 37 if fullname == SUBMOD_NAME: 38 raise ImportError('I cannot be loaded!') 39 40 41 class APITest: 42 43 """Test API-specific details for __import__ (e.g. raising the right 44 exception when passing in an int for the module name).""" 45 46 def test_raises_ModuleNotFoundError(self): 47 with self.assertRaises(ModuleNotFoundError): 48 util.import_importlib('some module that does not exist') 49 50 def test_name_requires_rparition(self): 51 # Raise TypeError if a non-string is passed in for the module name. 52 with self.assertRaises(TypeError): 53 self.__import__(42) 54 55 def test_negative_level(self): 56 # Raise ValueError when a negative level is specified. 57 # PEP 328 did away with sys.module None entries and the ambiguity of 58 # absolute/relative imports. 59 with self.assertRaises(ValueError): 60 self.__import__('os', globals(), level=-1) 61 62 def test_nonexistent_fromlist_entry(self): 63 # If something in fromlist doesn't exist, that's okay. 64 # issue15715 65 mod = types.ModuleType(PKG_NAME) 66 mod.__path__ = ['XXX'] 67 with util.import_state(meta_path=[self.bad_finder_loader]): 68 with util.uncache(PKG_NAME): 69 sys.modules[PKG_NAME] = mod 70 self.__import__(PKG_NAME, fromlist=['not here']) 71 72 def test_fromlist_load_error_propagates(self): 73 # If something in fromlist triggers an exception not related to not 74 # existing, let that exception propagate. 75 # issue15316 76 mod = types.ModuleType(PKG_NAME) 77 mod.__path__ = ['XXX'] 78 with util.import_state(meta_path=[self.bad_finder_loader]): 79 with util.uncache(PKG_NAME): 80 sys.modules[PKG_NAME] = mod 81 with self.assertRaises(ImportError): 82 self.__import__(PKG_NAME, 83 fromlist=[SUBMOD_NAME.rpartition('.')[-1]]) 84 85 86 class OldAPITests(APITest): 87 bad_finder_loader = BadLoaderFinder 88 89 90 (Frozen_OldAPITests, 91 Source_OldAPITests 92 ) = util.test_both(OldAPITests, __import__=util.__import__) 93 94 95 class SpecAPITests(APITest): 96 bad_finder_loader = BadSpecFinderLoader 97 98 99 (Frozen_SpecAPITests, 100 Source_SpecAPITests 101 ) = util.test_both(SpecAPITests, __import__=util.__import__) 102 103 104 if __name__ == '__main__': 105 unittest.main() 106