Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- def _gcd_import(name, package=None, level=0):
- """Import and return the module based on its name, the package the call is
- being made from, and the level adjustment.
- This function represents the greatest common denominator of functionality
- between import_module and __import__. This includes setting __package__ if
- the loader did not.
- """
- if package:
- if not hasattr(package, 'rindex'):
- raise ValueError("__package__ not set to a string")
- elif package not in sys.modules:
- msg = ("Parent module {0!r} not loaded, cannot perform relative "
- "import")
- raise SystemError(msg.format(package))
- if not name and level == 0:
- raise ValueError("Empty module name")
- if level > 0:
- dot = len(package)
- for x in range(level, 1, -1):
- try:
- dot = package.rindex('.', 0, dot)
- except ValueError:
- raise ValueError("attempted relative import beyond "
- "top-level package")
- if name:
- name = "{0}.{1}".format(package[:dot], name)
- else:
- name = package[:dot]
- with _ImportLockContext():
- try:
- module = sys.modules[name]
- if module is None:
- message = ("import of {} halted; "
- "None in sys.modules".format(name))
- raise ImportError(message)
- return module
- except KeyError:
- pass
- base = parent = ''
- module = None
- path = sys.path
- for part in name.split('.'):
- if parent and not path:
- msg = (_ERR_MSG + '; {} is not a package').format(name, parent)
- raise ImportError(msg)
- current = base + part
- module = sys.modules.get(current)
- if module is None:
- loader = _find_module(current, path)
- if loader is not None:
- if parent:
- _ensure_package(parent)
- loader.load_module(current)
- module = _fixup_module(current)
- if current != name:
- # update search path for the next target
- if hasattr(module, '__path__'):
- path = module.__path__
- else:
- path = get_module_path(current)
- parent = current
- base = parent + '.'
- if module is None:
- raise ImportError(_ERR_MSG.format(name))
- return module
- def get_module_path(modulename):
- if not modulename:
- return sys.path
- elif modulename in sys.virtual_package_paths:
- return sys.virtual_package_paths[modulename]
- elif modulename in sys.modules:
- path = getattr(sys.modules[modulename], '__path__', None)
- if path is not None:
- return path
- parent = modulename.rpartition('.')[0]
- path = VirtualPath(modulename, get_module_path(parent))
- return sys.virtual_package_paths.setdefault(modulename, path)
- def _fixup_module(name):
- """Ensure named module has a parent pointing to it, and a __package__"""
- # Backwards-compatibility; be nicer to skip the dict lookup.
- module = sys.modules[name]
- parent, _, child = name.rpartition('.')
- if parent:
- # Set the module as an attribute on its parent.
- setattr(sys.modules[parent], child, module)
- # Set __package__ if the loader did not.
- if not hasattr(module, '__package__') or module.__package__ is None:
- # Watch out for what comes out of sys.modules to not be a module,
- # e.g. an int.
- try:
- module.__package__ = module.__name__
- if not hasattr(module, '__path__'):
- module.__package__ = module.__package__.rpartition('.')[0]
- except AttributeError:
- pass
- return module
- def _find_module(name, path):
- meta_path = sys.meta_path + _IMPLICIT_META_PATH
- for finder in meta_path:
- loader = finder.find_module(name, path)
- if loader is not None:
- return loader
- else:
- return None
- def _ensure_package(name):
- if '.' in name:
- # Ensure parent package first
- _ensure_package(name.rpartition('.')[0])
- pkg = sys.modules.get(name)
- if pkg is None:
- pkg = sys.modules[name] = imp.new_module(name)
- if not hasattr(pkg, '__path__'):
- pkg.__path__ = get_module_path(name)
- return _fixup_module(pkg)
- class VirtualPath:
- __slots__ = ('__name__', '_parent', '_last_seen', '_path')
- def __init__(self, name, parent_path):
- self.__name__ = name
- self._parent = parent_path
- self._path = self._last_seen = ()
- def _fail(self, *args, **kw):
- raise TypeError(self.__name__+" is a virtual package")
- __getitem__ = __setitem__ = __delitem__ = append = extend = insert = _fail
- def _calculate(self):
- with _ImportLockContext():
- parent = tuple(self._parent)
- if parent != self._last_seen:
- items = []
- name = self.__name__
- for entry in parent:
- importer = get_importer(entry)
- if hasattr(importer, 'get_subpath'):
- item = importer.get_subpath(name)
- if item is not None:
- items.append(item)
- self._last_seen = parent
- self._path = tuple(items)
- return self._path
- def __iter__(self):
- return iter(self._calculate())
- def __len__(self):
- return len(self._calculate())
- def __repr__(self):
- return "VirtualPath" + repr((self.__name__, self._parent))
- def __contains__(self, item):
- return item in self._calculate()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement