def find_spec(cls, fullname, path=None, target=None): print(f"PathFinder.find_spec({fullname}, {path}) - called") """Try to find a spec for 'fullname' on sys.path or 'path'. The search is based on sys.path_hooks and sys.path_importer_cache. """ if path is None: path = sys.path spec = cls._get_spec(fullname, path, target) print(f"PathFinder. spec={spec}") if spec is None: return None elif spec.loader is None: namespace_path = spec.submodule_search_locations if namespace_path: # We found at least one namespace path. Return a spec which # can create the namespace package. spec.origin = None spec.submodule_search_locations = _NamespacePath( fullname, namespace_path, cls._get_spec ) return spec else: return None else: return spec
def test_minimum_sys_modules(): # builtins stay builtin_module = ModuleType('my_builtin') modules = {'my_builtin': builtin_module} new_modules = PEX.minimum_sys_modules([], modules) assert new_modules == modules new_modules = PEX.minimum_sys_modules(['bad_path'], modules) assert new_modules == modules # tainted evict tainted_module = ModuleType('tainted_module') tainted_module.__path__ = ['bad_path'] modules = {'tainted_module': tainted_module} new_modules = PEX.minimum_sys_modules([], modules) assert new_modules == modules new_modules = PEX.minimum_sys_modules(['bad_path'], modules) assert new_modules == {} assert tainted_module.__path__ == [] # tainted cleaned tainted_module = ModuleType('tainted_module') tainted_module.__path__ = ['bad_path', 'good_path'] modules = {'tainted_module': tainted_module} new_modules = PEX.minimum_sys_modules([], modules) assert new_modules == modules new_modules = PEX.minimum_sys_modules(['bad_path'], modules) assert new_modules == modules assert tainted_module.__path__ == ['good_path'] # If __path__ is not a list the module is removed; typically this implies # it's a namespace package (https://www.python.org/dev/peps/pep-0420/) where # __path__ is a _NamespacePath. try: from importlib._bootstrap_external import _NamespacePath bad_path = _NamespacePath("hello", "world", None) except ImportError: bad_path = {"hello": "world"} class FakeModule(object): pass tainted_module = FakeModule() tainted_module.__path__ = bad_path # Not a list as expected modules = {'tainted_module': tainted_module} new_modules = PEX.minimum_sys_modules(['bad_path'], modules) assert new_modules == {}
def test_minimum_sys_modules(): # tainted modules evict tainted_module = ModuleType("tainted_module") tainted_module.__file__ = "bad_path" modules = {"tainted_module": tainted_module} new_modules = PEX.minimum_sys_modules(site_libs=[], modules=modules) assert new_modules == modules new_modules = PEX.minimum_sys_modules(site_libs=["bad_path"], modules=modules) assert new_modules == {} # builtins stay builtin_module = ModuleType("my_builtin") stdlib_module = ModuleType("my_stdlib") stdlib_module.__file__ = "good_path" modules = {"my_builtin": builtin_module, "my_stdlib": stdlib_module} new_modules = PEX.minimum_sys_modules(site_libs=[], modules=modules) assert new_modules == modules new_modules = PEX.minimum_sys_modules(site_libs=["bad_path"], modules=modules) assert new_modules == modules # tainted packages evict tainted_module = ModuleType("tainted_module") tainted_module.__path__ = ["bad_path"] modules = {"tainted_module": tainted_module} new_modules = PEX.minimum_sys_modules(site_libs=[], modules=modules) assert new_modules == modules new_modules = PEX.minimum_sys_modules(site_libs=["bad_path"], modules=modules) assert new_modules == {} assert tainted_module.__path__ == [] # tainted packages cleaned tainted_module = ModuleType("tainted_module") tainted_module.__path__ = ["bad_path", "good_path"] modules = {"tainted_module": tainted_module} new_modules = PEX.minimum_sys_modules(site_libs=[], modules=modules) assert new_modules == modules new_modules = PEX.minimum_sys_modules(site_libs=["bad_path"], modules=modules) assert new_modules == modules assert tainted_module.__path__ == ["good_path"] # If __path__ is not a list the module is removed; typically this implies # it's a namespace package (https://www.python.org/dev/peps/pep-0420/) where # __path__ is a _NamespacePath. try: from importlib._bootstrap_external import _NamespacePath bad_path = _NamespacePath("hello", "world", None) except ImportError: bad_path = {"hello": "world"} class FakeModule(object): pass tainted_module = FakeModule() tainted_module.__path__ = bad_path # Not a list as expected modules = {"tainted_module": tainted_module} new_modules = PEX.minimum_sys_modules(site_libs=["bad_path"], modules=modules) assert new_modules == {} # If __file__ is explicitly None we should gracefully proceed to __path__ checks. tainted_module = ModuleType("tainted_module") tainted_module.__file__ = None modules = {"tainted_module": tainted_module} new_modules = PEX.minimum_sys_modules(site_libs=[], modules=modules) assert new_modules == modules