diff --git a/Lib/imp.py b/Lib/imp.py --- a/Lib/imp.py +++ b/Lib/imp.py @@ -14,7 +14,7 @@ from _imp import (get_magic, get_tag, get_suffixes, cache_from_source, source_from_cache) # Should be re-implemented here (and mostly deprecated) -from _imp import (find_module, load_compiled, NullImporter, +from _imp import (load_compiled, NullImporter, SEARCH_ERROR, PY_SOURCE, PY_COMPILED, C_EXTENSION, PY_RESOURCE, PKG_DIRECTORY, C_BUILTIN, PY_FROZEN, PY_CODERESOURCE, IMP_HOOK) @@ -23,6 +23,8 @@ from importlib import _bootstrap import os +import sys +import tokenize class _LoadSourceCompatibility(_bootstrap._SourceFileLoader): @@ -65,6 +67,90 @@ return _bootstrap._SourceFileLoader(name, path).load_module(name) +def _resolve_fullname(name, path): + if not path: + return name + if sys.path[0] in ('', '.'): + syspath = sys.path[:] + syspath[0] = os.getcwd() + else: + syspath = sys.path + # match up the path list to sys.path + for pkgdir in path: + for sysdir in syspath: + if pkgdir.startswith(sysdir): + pkgdir = pkgdir[len(sysdir):] + break + else: + continue + break + else: + raise ImportError("No module named {!r}".format(name), name=name) + # build the new module name + if not pkgdir: + return name + pkgdir = pkgdir.lstrip(os.sep) + return ('.'.join(pkgdir.split(os.sep) + [name]) if pkgdir else name) + + +_MODULE_TYPES = { + _bootstrap.BuiltinImporter: C_BUILTIN, + _bootstrap.FrozenImporter: PY_FROZEN, + _bootstrap._ExtensionFileLoader: C_EXTENSION, + _bootstrap._SourcelessFileLoader: PY_COMPILED, + _bootstrap._SourceFileLoader: PY_SOURCE, + } + +def find_module(name, path=None): + """Search for a module and return the tuple representing it. + + If path is omitted or None, search for a built-in, frozen or special + module and continue search in sys.path. The module name cannot + contain '.'; to search for a submodule of a package, pass the + submodule name and the package's __path__. + + usage: + find_module(name, [path]) -> (file, filename, (suffix, mode, type)) + + """ + + fullname = _resolve_fullname(name, path) + loader = _bootstrap._find_module(fullname, path) + + # defaults + file = None + filename = None + suffix = "" + mode = '' + + print(loader) + try: + filetype = _MODULE_TYPES[type(loader)] + except KeyError: + raise ImportError("unknown module type", name=name) + + # XXX handle MS_COREDLL case? + + if filetype in (C_BUILTIN, PY_FROZEN): + pass + elif loader.is_package(fullname): + filename = os.path.dirname(loader.get_filename(fullname)) + filetype = PKG_DIRECTORY + else: + filename = loader.get_filename(fullname) + for suffix in _bootstrap._suffix_list(filetype): + if filename.endswith(suffix): + mode = 'r' # loader.MODE + with open(filename, 'rb') as bytesfile: + encoding = tokenize.detect_encoding(bytesfile.readline)[0] + file = open(filename, mode, encoding=encoding) + break + else: + suffix = "" + + return (file, filename, (suffix, mode, filetype)) + + def load_module(name, file, filename, details): """Load a module, given information returned by find_module().