1""" 2Re-implementation of find_module and get_frozen_object 3from the deprecated imp module. 4""" 5 6import os 7import importlib.util 8import importlib.machinery 9 10from .py34compat import module_from_spec 11 12 13PY_SOURCE = 1 14PY_COMPILED = 2 15C_EXTENSION = 3 16C_BUILTIN = 6 17PY_FROZEN = 7 18 19 20def find_spec(module, paths): 21 finder = ( 22 importlib.machinery.PathFinder().find_spec 23 if isinstance(paths, list) else 24 importlib.util.find_spec 25 ) 26 return finder(module, paths) 27 28 29def find_module(module, paths=None): 30 """Just like 'imp.find_module()', but with package support""" 31 spec = find_spec(module, paths) 32 if spec is None: 33 raise ImportError("Can't find %s" % module) 34 if not spec.has_location and hasattr(spec, 'submodule_search_locations'): 35 spec = importlib.util.spec_from_loader('__init__.py', spec.loader) 36 37 kind = -1 38 file = None 39 static = isinstance(spec.loader, type) 40 if spec.origin == 'frozen' or static and issubclass( 41 spec.loader, importlib.machinery.FrozenImporter): 42 kind = PY_FROZEN 43 path = None # imp compabilty 44 suffix = mode = '' # imp compatibility 45 elif spec.origin == 'built-in' or static and issubclass( 46 spec.loader, importlib.machinery.BuiltinImporter): 47 kind = C_BUILTIN 48 path = None # imp compabilty 49 suffix = mode = '' # imp compatibility 50 elif spec.has_location: 51 path = spec.origin 52 suffix = os.path.splitext(path)[1] 53 mode = 'r' if suffix in importlib.machinery.SOURCE_SUFFIXES else 'rb' 54 55 if suffix in importlib.machinery.SOURCE_SUFFIXES: 56 kind = PY_SOURCE 57 elif suffix in importlib.machinery.BYTECODE_SUFFIXES: 58 kind = PY_COMPILED 59 elif suffix in importlib.machinery.EXTENSION_SUFFIXES: 60 kind = C_EXTENSION 61 62 if kind in {PY_SOURCE, PY_COMPILED}: 63 file = open(path, mode) 64 else: 65 path = None 66 suffix = mode = '' 67 68 return file, path, (suffix, mode, kind) 69 70 71def get_frozen_object(module, paths=None): 72 spec = find_spec(module, paths) 73 if not spec: 74 raise ImportError("Can't find %s" % module) 75 return spec.loader.get_code(module) 76 77 78def get_module(module, paths, info): 79 spec = find_spec(module, paths) 80 if not spec: 81 raise ImportError("Can't find %s" % module) 82 return module_from_spec(spec) 83