test_timeout = None # _release_save() unsupported test_release_save_unacquired = None # lock status in repr unsupported test_repr = None test_locked_repr = None LOCK_TYPES = { kind: splitinit._bootstrap._ModuleLock for kind, splitinit in init.items() } (Frozen_ModuleLockAsRLockTests, Source_ModuleLockAsRLockTests) = test_util.test_both(ModuleLockAsRLockTests, lock_tests.RLockTests, LockType=LOCK_TYPES) class DeadlockAvoidanceTests: def setUp(self): try: self.old_switchinterval = sys.getswitchinterval() support.setswitchinterval(0.000001) except AttributeError: self.old_switchinterval = None def tearDown(self): if self.old_switchinterval is not None: sys.setswitchinterval(self.old_switchinterval)
try: cached = self.loc_spec.cached finally: sys.implementation.cache_tag = original self.assertIs(cached, None) def test_cached_sourceless(self): self.loc_spec.origin = 'spam.pyc' self.assertEqual(self.loc_spec.cached, 'spam.pyc') (Frozen_ModuleSpecTests, Source_ModuleSpecTests ) = test_util.test_both(ModuleSpecTests, util=util, machinery=machinery) class ModuleSpecMethodsTests: @property def bootstrap(self): return self.init._bootstrap def setUp(self): self.name = 'spam' self.path = 'spam.py' self.cached = self.util.cache_from_source(self.path) self.loader = TestLoader() self.spec = self.machinery.ModuleSpec(self.name, self.loader) self.loc_spec = self.machinery.ModuleSpec(self.name, self.loader,
self.assertTrue( issubclass(self.__test, superclass), "{0} is not a superclass of {1}".format( superclass, self.__test)) class MetaPathFinder(InheritanceTests): superclass_names = [] subclass_names = [ 'BuiltinImporter', 'FrozenImporter', 'PathFinder', 'WindowsRegistryFinder' ] (Frozen_MetaPathFinderInheritanceTests, Source_MetaPathFinderInheritanceTests) = test_util.test_both(MetaPathFinder, abc=abc) class PathEntryFinder(InheritanceTests): superclass_names = [] subclass_names = ['FileFinder'] (Frozen_PathEntryFinderInheritanceTests, Source_PathEntryFinderInheritanceTests) = test_util.test_both(PathEntryFinder, abc=abc) class ResourceLoader(InheritanceTests): superclass_names = ['Loader']
with open(source, 'wb') as fp: fp.write(b'state = "new"') loader.exec_module(mod) self.assertEqual(mod.state, 'new') with open(pyc, 'rb') as fp: data = fp.read() self.assertEqual(int.from_bytes(data[4:8], 'little'), 0b1) self.assertEqual( self.util.source_hash(b'state = "new"'), data[8:16], ) (Frozen_SimpleTest, Source_SimpleTest) = util.test_both(SimpleTest, importlib=importlib, machinery=machinery, abc=importlib_abc, util=importlib_util) class SourceDateEpochTestMeta(SourceDateEpochTestMeta, type(Source_SimpleTest)): pass class SourceDateEpoch_SimpleTest(Source_SimpleTest, metaclass=SourceDateEpochTestMeta, source_date_epoch=True): pass
return None def exec_module(self, module): pass class SpecLoaderAttributeTests: def test___loader__(self): loader = SpecLoaderMock() with util.uncache('blah'), util.import_state(meta_path=[loader]): module = self.__import__('blah') self.assertEqual(loader, module.__loader__) (Frozen_SpecTests, Source_SpecTests) = util.test_both(SpecLoaderAttributeTests, __import__=util.__import__) class LoaderMock: def find_module(self, fullname, path=None): return self def load_module(self, fullname): sys.modules[fullname] = self.module return self.module class LoaderAttributeTests: def test___loader___missing(self): with warnings.catch_warnings(): warnings.simplefilter("ignore", ImportWarning)
def test_unloadable(self): name = 'asdfjkl;' with self.assertRaises(ImportError) as cm: self.load_module(name) self.assertEqual(cm.exception.name, name) def test_is_package(self): self.assertFalse(self.loader.is_package(util.EXTENSIONS.name)) for suffix in self.machinery.EXTENSION_SUFFIXES: path = os.path.join('some', 'path', 'pkg', '__init__' + suffix) loader = self.machinery.ExtensionFileLoader('pkg', path) self.assertTrue(loader.is_package('pkg')) (Frozen_LoaderTests, Source_LoaderTests ) = util.test_both(LoaderTests, machinery=machinery) class MultiPhaseExtensionModuleTests(abc.LoaderTests): # Test loading extension modules with multi-phase initialization (PEP 489). def setUp(self): if not self.machinery.EXTENSION_SUFFIXES: raise unittest.SkipTest("Requires dynamic loading support.") self.name = '_testmultiphase' finder = self.machinery.FileFinder(None) self.spec = importlib.util.find_spec(self.name) assert self.spec self.loader = self.machinery.ExtensionFileLoader( self.name, self.spec.origin) def load_module(self):
module, output = self.exec_module(name) self.assertEqual(repr(module), "<module '__hello__' (frozen)>") # No way to trigger an error in a frozen module. test_state_after_failure = None def test_unloadable(self): with import_helper.frozen_modules(): assert self.machinery.FrozenImporter.find_spec('_not_real') is None with self.assertRaises(ImportError) as cm: self.exec_module('_not_real') self.assertEqual(cm.exception.name, '_not_real') (Frozen_ExecModuleTests, Source_ExecModuleTests) = util.test_both(ExecModuleTests, machinery=machinery) class LoaderTests(abc.LoaderTests): def load_module(self, name): with fresh(name, oldapi=True): module = self.machinery.FrozenImporter.load_module(name) with captured_stdout() as stdout: module.main() return module, stdout def test_module(self): module, stdout = self.load_module('__hello__') filename = resolve_stdlib_file('__hello__') check = { '__name__': '__hello__',
finder = self.machinery.FileFinder(util.EXTENSIONS.path, (self.machinery.ExtensionFileLoader, self.machinery.EXTENSION_SUFFIXES)) return finder.find_spec(bad_name) @unittest.skipIf(sys.flags.ignore_environment, 'ignore_environment flag was set') def test_case_sensitive(self): with os_helper.EnvironmentVarGuard() as env: env.unset('PYTHONCASEOK') self.caseok_env_changed(should_exist=False) spec = self.find_spec() self.assertIsNone(spec) @unittest.skipIf(sys.flags.ignore_environment, 'ignore_environment flag was set') def test_case_insensitivity(self): with os_helper.EnvironmentVarGuard() as env: env.set('PYTHONCASEOK', '1') self.caseok_env_changed(should_exist=True) spec = self.find_spec() self.assertTrue(spec) (Frozen_ExtensionCaseSensitivity, Source_ExtensionCaseSensitivity ) = util.test_both(ExtensionModuleCaseSensitivityTest, importlib=importlib, machinery=machinery) if __name__ == '__main__': unittest.main()
assert not hasattr(sys, '__path__') with self.assertRaises(ImportError) as cm: self.__import__('sys.no_submodules_here') self.assertEqual(cm.exception.name, 'sys.no_submodules_here') def test_module_not_package_but_side_effects(self): # If a module injects something into sys.modules as a side-effect, then # pick up on that fact. name = 'mod' subname = name + '.b' def module_injection(): sys.modules[subname] = 'total bunk' mock_spec = util.mock_spec('mod', module_code={'mod': module_injection}) with mock_spec as mock: with util.import_state(meta_path=[mock]): try: submodule = self.__import__(subname) finally: import_helper.unload(subname) (Frozen_ParentTests, Source_ParentTests) = util.test_both(ParentModuleTests, __import__=util.__import__) if __name__ == '__main__': unittest.main()
try: cached = self.loc_spec.cached finally: sys.implementation.cache_tag = original self.assertIs(cached, None) def test_cached_sourceless(self): self.loc_spec.origin = 'spam.pyc' self.assertEqual(self.loc_spec.cached, 'spam.pyc') (Frozen_ModuleSpecTests, Source_ModuleSpecTests) = test_util.test_both(ModuleSpecTests, util=util, machinery=machinery) class ModuleSpecMethodsTests: @property def bootstrap(self): return self.init._bootstrap def setUp(self): self.name = 'spam' self.path = 'spam.py' self.cached = self.util.cache_from_source(self.path) self.loader = TestLoader() self.spec = self.machinery.ModuleSpec(self.name, self.loader) self.loc_spec = self.machinery.ModuleSpec(self.name,
class Using__package__PEP302(Using__package__): mock_modules = util.mock_modules def test_using___package__(self): with warnings.catch_warnings(): warnings.simplefilter("ignore", ImportWarning) super().test_using___package__() def test_spec_fallback(self): with warnings.catch_warnings(): warnings.simplefilter("ignore", ImportWarning) super().test_spec_fallback() (Frozen_UsingPackagePEP302, Source_UsingPackagePEP302) = util.test_both(Using__package__PEP302, __import__=util.__import__) class Using__package__PEP451(Using__package__): mock_modules = util.mock_spec (Frozen_UsingPackagePEP451, Source_UsingPackagePEP451) = util.test_both(Using__package__PEP451, __import__=util.__import__) class Setting__package__: """Because __package__ is a new feature, it is not always set by a loader. Import will set it as needed to help with the transition to relying on __package__.
def test_relative_import_no_globals(self): # No globals for a relative import is an error. with warnings.catch_warnings(): warnings.simplefilter("ignore") with self.assertRaises(KeyError): self.__import__('sys', level=1) def test_relative_import_no_package(self): with self.assertRaises(ImportError): self.__import__('a', { '__package__': '', '__spec__': None }, level=1) def test_relative_import_no_package_exists_absolute(self): with self.assertRaises(ImportError): self.__import__('sys', { '__package__': '', '__spec__': None }, level=1) (Frozen_RelativeImports, Source_RelativeImports) = util.test_both(RelativeImports, __import__=util.__import__) if __name__ == '__main__': unittest.main()
self.assertEqual(cm.exception.name, name) def test_already_imported(self): # Using the name of a module already imported but not a built-in should # still fail. module_name = 'builtin_reload_test' assert module_name not in sys.builtin_module_names with util.uncache(module_name): module = types.ModuleType(module_name) sys.modules[module_name] = module with self.assertRaises(ImportError) as cm: self.load_module(module_name) self.assertEqual(cm.exception.name, module_name) (Frozen_LoaderTests, Source_LoaderTests) = util.test_both(LoaderTests, machinery=machinery) @unittest.skipIf(util.BUILTINS.good_name is None, 'no reasonable builtin module') class InspectLoaderTests: """Tests for InspectLoader methods for BuiltinImporter.""" def test_get_code(self): # There is no code object. result = self.machinery.BuiltinImporter.get_code( util.BUILTINS.good_name) self.assertIsNone(result) def test_get_source(self): # There is no source. result = self.machinery.BuiltinImporter.get_source(
def load_a(): self.init.import_module('a.b') def load_b(): nonlocal b_load_count b_load_count += 1 code = {'a': load_a, 'a.b': load_b} modules = ['a.__init__', 'a.b'] with test_util.mock_spec(*modules, module_code=code) as mock: with test_util.import_state(meta_path=[mock]): self.init.import_module('a.b') self.assertEqual(b_load_count, 1) (Frozen_ImportModuleTests, Source_ImportModuleTests ) = test_util.test_both(ImportModuleTests, init=init) class FindLoaderTests: FakeMetaFinder = None def test_sys_modules(self): # If a module with __loader__ is in sys.modules, then return it. name = 'some_mod' with test_util.uncache(name): module = types.ModuleType(name) loader = 'a loader!' module.__loader__ = loader sys.modules[name] = module with warnings.catch_warnings():
from test.test_importlib import util machinery = util.import_importlib('importlib.machinery') import unittest class PathHookTests: """Test the path hook for extension modules.""" # XXX Should it only succeed for pre-existing directories? # XXX Should it only work for directories containing an extension module? def hook(self, entry): return self.machinery.FileFinder.path_hook( (self.machinery.ExtensionFileLoader, self.machinery.EXTENSION_SUFFIXES))(entry) def test_success(self): # Path hook should handle a directory where a known extension module # exists. self.assertTrue(hasattr(self.hook(util.EXTENSIONS.path), 'find_module')) (Frozen_PathHooksTests, Source_PathHooksTests) = util.test_both(PathHookTests, machinery=machinery) if __name__ == '__main__': unittest.main()
finder = self.get_finder(file_obj.name) found = self._find(finder, 'doesnotexist') self.assertEqual(found, self.NOT_FOUND) class FinderTestsPEP451(FinderTests): NOT_FOUND = None def _find(self, finder, name, loader_only=False): spec = finder.find_spec(name) return spec.loader if spec is not None else spec (Frozen_FinderTestsPEP451, Source_FinderTestsPEP451) = util.test_both(FinderTestsPEP451, machinery=machinery) class FinderTestsPEP420(FinderTests): NOT_FOUND = (None, []) def _find(self, finder, name, loader_only=False): with warnings.catch_warnings(): warnings.simplefilter("ignore", DeprecationWarning) loader_portions = finder.find_loader(name) return loader_portions[0] if loader_only else loader_portions (Frozen_FinderTestsPEP420, Source_FinderTestsPEP420) = util.test_both(FinderTestsPEP420,
source = codecs.BOM_UTF8 + self.create_source('latin-1') with self.assertRaises(SyntaxError): self.run_test(source) class EncodingTestPEP451(EncodingTest): def load(self, loader): module = types.ModuleType(self.module_name) module.__spec__ = importlib.util.spec_from_loader( self.module_name, loader) loader.exec_module(module) return module (Frozen_EncodingTestPEP451, Source_EncodingTestPEP451) = util.test_both(EncodingTestPEP451, machinery=machinery) class EncodingTestPEP302(EncodingTest): def load(self, loader): with warnings.catch_warnings(): warnings.simplefilter('ignore', DeprecationWarning) return loader.load_module(self.module_name) (Frozen_EncodingTestPEP302, Source_EncodingTestPEP302) = util.test_both(EncodingTestPEP302, machinery=machinery) class LineEndingTest:
with util.uncache('some_module'): sys.modules['some_module'] = module_to_use module = self.__import__('some_module') self.assertEqual(id(module_to_use), id(module)) def test_None_in_cache(self): #[None in cache] name = 'using_None' with util.uncache(name): sys.modules[name] = None with self.assertRaises(ImportError) as cm: self.__import__(name) self.assertEqual(cm.exception.name, name) (Frozen_UseCache, Source_UseCache) = util.test_both(UseCache, __import__=util.__import__) class ImportlibUseCache(UseCache, unittest.TestCase): # Pertinent only to PEP 302; exec_module() doesn't return a module. __import__ = util.__import__['Source'] def create_mock(self, *names, return_=None): mock = util.mock_modules(*names) original_load = mock.load_module def load_module(self, fullname): original_load(fullname) return return_
self.init.import_module('a.b') def load_b(): nonlocal b_load_count b_load_count += 1 code = {'a': load_a, 'a.b': load_b} modules = ['a.__init__', 'a.b'] with test_util.mock_spec(*modules, module_code=code) as mock: with test_util.import_state(meta_path=[mock]): self.init.import_module('a.b') self.assertEqual(b_load_count, 1) (Frozen_ImportModuleTests, Source_ImportModuleTests) = test_util.test_both(ImportModuleTests, init=init) class FindLoaderTests: FakeMetaFinder = None def test_sys_modules(self): # If a module with __loader__ is in sys.modules, then return it. name = 'some_mod' with test_util.uncache(name): module = types.ModuleType(name) loader = 'a loader!' module.__loader__ = loader sys.modules[name] = module with warnings.catch_warnings():
def test_unloadable(self): name = 'asdfjkl;' with self.assertRaises(ImportError) as cm: self.load_module(name) self.assertEqual(cm.exception.name, name) def test_is_package(self): self.assertFalse(self.loader.is_package(util.EXTENSIONS.name)) for suffix in self.machinery.EXTENSION_SUFFIXES: path = os.path.join('some', 'path', 'pkg', '__init__' + suffix) loader = self.machinery.ExtensionFileLoader('pkg', path) self.assertTrue(loader.is_package('pkg')) (Frozen_LoaderTests, Source_LoaderTests) = util.test_both(LoaderTests, machinery=machinery) class MultiPhaseExtensionModuleTests(abc.LoaderTests): # Test loading extension modules with multi-phase initialization (PEP 489). def setUp(self): if not self.machinery.EXTENSION_SUFFIXES: raise unittest.SkipTest("Requires dynamic loading support.") self.name = '_testmultiphase' if self.name in sys.builtin_module_names: raise unittest.SkipTest(f"{self.name} is a builtin module") finder = self.machinery.FileFinder(None) self.spec = importlib.util.find_spec(self.name) assert self.spec self.loader = self.machinery.ExtensionFileLoader(
self.assertIsNotNone(sensitive) self.assertIn(self.name, sensitive.get_filename(self.name)) self.assertIsNotNone(insensitive) self.assertIn(self.name, insensitive.get_filename(self.name)) class CaseSensitivityTestPEP302(CaseSensitivityTest): def find(self, finder): with warnings.catch_warnings(): warnings.simplefilter("ignore", DeprecationWarning) return finder.find_module(self.name) (Frozen_CaseSensitivityTestPEP302, Source_CaseSensitivityTestPEP302) = util.test_both(CaseSensitivityTestPEP302, importlib=importlib, machinery=machinery) class CaseSensitivityTestPEP451(CaseSensitivityTest): def find(self, finder): found = finder.find_spec(self.name) return found.loader if found is not None else found (Frozen_CaseSensitivityTestPEP451, Source_CaseSensitivityTestPEP451) = util.test_both(CaseSensitivityTestPEP451, importlib=importlib, machinery=machinery) if __name__ == '__main__':
self.assertEqual(cache, {}) class FindModuleTests(FinderTests): def find(self, *args, **kwargs): with warnings.catch_warnings(): warnings.simplefilter("ignore", DeprecationWarning) return self.machinery.PathFinder.find_module(*args, **kwargs) def check_found(self, found, importer): self.assertIs(found, importer) (Frozen_FindModuleTests, Source_FindModuleTests) = util.test_both(FindModuleTests, importlib=importlib, machinery=machinery) class FindSpecTests(FinderTests): def find(self, *args, **kwargs): return self.machinery.PathFinder.find_spec(*args, **kwargs) def check_found(self, found, importer): self.assertIs(found.loader, importer) (Frozen_FindSpecTests, Source_FindSpecTests) = util.test_both(FindSpecTests, importlib=importlib, machinery=machinery)
def test_nonexistent_fromlist_entry(self): with warnings.catch_warnings(): warnings.simplefilter("ignore", ImportWarning) super().test_nonexistent_fromlist_entry() def test_fromlist_load_error_propagates(self): with warnings.catch_warnings(): warnings.simplefilter("ignore", ImportWarning) super().test_fromlist_load_error_propagates def test_blocked_fromlist(self): with warnings.catch_warnings(): warnings.simplefilter("ignore", ImportWarning) super().test_blocked_fromlist() (Frozen_OldAPITests, Source_OldAPITests) = util.test_both(OldAPITests, __import__=util.__import__) class SpecAPITests(APITest): bad_finder_loader = BadSpecFinderLoader (Frozen_SpecAPITests, Source_SpecAPITests) = util.test_both(SpecAPITests, __import__=util.__import__) if __name__ == '__main__': unittest.main()
f"{util.EXTENSIONS.name} is a builtin module") def find_spec(self, fullname): importer = self.machinery.FileFinder( util.EXTENSIONS.path, (self.machinery.ExtensionFileLoader, self.machinery.EXTENSION_SUFFIXES)) return importer.find_spec(fullname) def test_module(self): self.assertTrue(self.find_spec(util.EXTENSIONS.name)) # No extension module as an __init__ available for testing. test_package = test_package_in_package = None # No extension module in a package available for testing. test_module_in_package = None # Extension modules cannot be an __init__ for a package. test_package_over_module = None def test_failure(self): self.assertIsNone(self.find_spec('asdfjkl;')) (Frozen_FinderTests, Source_FinderTests) = util.test_both(FinderTests, machinery=machinery) if __name__ == '__main__': unittest.main()
def test_specified_encoding(self): source = '# coding=latin-1\n' + self.source source_bytes = source.encode('latin-1') assert source_bytes != source.encode('utf-8') self.assertEqual(self.util.decode_source(source_bytes), source) def test_universal_newlines(self): source = '\r\n'.join([self.source, self.source]) source_bytes = source.encode('utf-8') self.assertEqual(self.util.decode_source(source_bytes), '\n'.join([self.source, self.source])) (Frozen_DecodeSourceBytesTests, Source_DecodeSourceBytesTests ) = util.test_both(DecodeSourceBytesTests, util=importlib_util) class ModuleFromSpecTests: def test_no_create_module(self): class Loader: def exec_module(self, module): pass spec = self.machinery.ModuleSpec('test', Loader()) with self.assertRaises(ImportError): module = self.util.module_from_spec(spec) def test_create_module_returns_None(self): class Loader(self.abc.Loader): def create_module(self, spec):
# [import return] with util.mock_spec('pkg.__init__', 'pkg.module') as importer: with util.import_state(meta_path=[importer]): module = self.__import__('pkg.module') self.assertEqual(module.__name__, 'pkg') def test_return_from_from_import(self): # [from return] with util.mock_spec('pkg.__init__', 'pkg.module') as importer: with util.import_state(meta_path=[importer]): module = self.__import__('pkg.module', fromlist=['attr']) self.assertEqual(module.__name__, 'pkg.module') (Frozen_ReturnValue, Source_ReturnValue) = util.test_both(ReturnValue, __import__=util.__import__) class HandlingFromlist: """Using fromlist triggers different actions based on what is being asked of it. If fromlist specifies an object on a module, nothing special happens [object case]. This is even true if the object does not exist [bad object]. If a package is being imported, then what is listed in fromlist may be treated as a module to be imported [module]. And this extends to what is contained in __all__ when '*' is imported [using *]. And '*' does not need to be the only name in the fromlist [using * with others]. """
class PathHookTest: """Test the path hook for source.""" def path_hook(self): return self.machinery.FileFinder.path_hook( (self.machinery.SourceFileLoader, self.machinery.SOURCE_SUFFIXES)) def test_success(self): with util.create_modules('dummy') as mapping: self.assertTrue( hasattr(self.path_hook()(mapping['.root']), 'find_spec')) def test_success_legacy(self): with util.create_modules('dummy') as mapping: self.assertTrue( hasattr(self.path_hook()(mapping['.root']), 'find_module')) def test_empty_string(self): # The empty string represents the cwd. self.assertTrue(hasattr(self.path_hook()(''), 'find_spec')) def test_empty_string_legacy(self): # The empty string represents the cwd. self.assertTrue(hasattr(self.path_hook()(''), 'find_module')) (Frozen_PathHookTest, Source_PathHooktest) = util.test_both(PathHookTest, machinery=machinery) if __name__ == '__main__': unittest.main()
spec = self.machinery.WindowsRegistryFinder.find_spec(self.test_module) self.assertIsNot(loader, None) self.assertIsNot(spec, None) def test_module_not_found(self): with setup_module(self.machinery, self.test_module, path="."): with warnings.catch_warnings(): warnings.simplefilter("ignore", DeprecationWarning) loader = self.machinery.WindowsRegistryFinder.find_module(self.test_module) spec = self.machinery.WindowsRegistryFinder.find_spec(self.test_module) self.assertIsNone(loader) self.assertIsNone(spec) (Frozen_WindowsRegistryFinderTests, Source_WindowsRegistryFinderTests ) = test_util.test_both(WindowsRegistryFinderTests, machinery=machinery) @unittest.skipUnless(sys.platform.startswith('win'), 'requires Windows') class WindowsExtensionSuffixTests: def test_tagged_suffix(self): suffixes = self.machinery.EXTENSION_SUFFIXES expected_tag = ".cp{0.major}{0.minor}-{1}.pyd".format(sys.version_info, re.sub('[^a-zA-Z0-9]', '_', get_platform())) try: untagged_i = suffixes.index(".pyd") except ValueError: untagged_i = suffixes.index("_d.pyd") expected_tag = "_d" + expected_tag self.assertIn(expected_tag, suffixes)
module_name = 'nothing' try: del sys.modules[module_name] except KeyError: pass with util.import_state(meta_path=[]): with warnings.catch_warnings(record=True) as w: warnings.simplefilter('always') self.assertIsNone( importlib._bootstrap._find_spec('nothing', None)) self.assertEqual(len(w), 1) self.assertTrue(issubclass(w[-1].category, ImportWarning)) (Frozen_CallingOrder, Source_CallingOrder) = util.test_both(CallingOrder, __import__=util.__import__) class CallSignature: """If there is no __path__ entry on the parent module, then 'path' is None [no path]. Otherwise, the value for __path__ is passed in for the 'path' argument [path set].""" def log_finder(self, importer): fxn = getattr(importer, self.finder_name) log = [] def wrapper(self, *args, **kwargs): log.append([args, kwargs]) return fxn(*args, **kwargs) return log, wrapper