Esempio n. 1
0
def _is_dynamic(module):
    """
    Return True if the module is special module that cannot be imported by its
    name.
    """
    # Quick check: module that have __file__ attribute are not dynamic modules.
    if hasattr(module, '__file__'):
        return False

    if module.__spec__ is not None:
        return False

    # In PyPy, Some built-in modules such as _codecs can have their
    # __spec__ attribute set to None despite being imported.  For such
    # modules, the ``_find_spec`` utility of the standard library is used.
    parent_name = module.__name__.rpartition('.')[0]
    if parent_name:  # pragma: no cover
        # This code handles the case where an imported package (and not
        # module) remains with __spec__ set to None. It is however untested
        # as no package in the PyPy stdlib has __spec__ set to None after
        # it is imported.
        try:
            parent = sys.modules[parent_name]
        except KeyError:
            msg = "parent {!r} not in sys.modules"
            raise ImportError(msg.format(parent_name))
        else:
            pkgpath = parent.__path__
    else:
        pkgpath = None
    return _find_spec(module.__name__, pkgpath, module) is None
Esempio n. 2
0
def find_spec(name, package=None) -> ModuleSpec:
    """Return the spec for the specified module.

    Note: this is a modification of importlib.util.find_spec which does not
    import parent packages. It instead recursively searches through the parents.

    First, sys.modules is checked to see if the module was already imported. If
    so, then sys.modules[name].__spec__ is returned. If that happens to be
    set to None, then ValueError is raised. If the module is not in
    sys.modules, then sys.meta_path is searched for a suitable spec with the
    value of 'path' given to the finders. None is returned if no spec could
    be found.

    If the name is for submodule (contains a dot), find_spec is called on the
    parent module to determine the submodule_search_locations.

    The name and package arguments work the same as importlib.import_module().
    In other words, relative module names (with leading dots) work.

    """
    fullname = resolve_name(name, package) if name.startswith('.') else name
    if fullname not in sys.modules:
        parent_name = fullname.rpartition('.')[0]
        if parent_name:
            # Use builtins.__import__() in case someone replaced it.
            parent = find_spec(parent_name, package=package)
            return _find_spec(fullname, parent.submodule_search_locations)
        else:
            return _find_spec(fullname, None)
    else:
        module = sys.modules[fullname]
        if module is None:
            return None
        try:
            spec = module.__spec__
        except AttributeError:
            raise ValueError('{}.__spec__ is not set'.format(name)) from None
        else:
            if spec is None:
                raise ValueError('{}.__spec__ is None'.format(name))
            return spec
Esempio n. 3
0
    def find_spec(self, fullName, path, target=None, *args, **kwargs):
        #print(groups.Fore.lightredEx("find_spec")+" "+groups.Fore.lightcyanEx(fullName), path, target, args, kwargs)
        if not fullName.startswith(__class__.marker):
            #import traceback
            #traceback.print_stack()
            return None
        else:
            trueName = fullName[len(__class__.marker):]
            #print("trueName", trueName)
            trueNameComponents = trueName.split(".")
            #print(trueNameComponents)

            try:
                if len(trueNameComponents) == 1:
                    origSpec = importlib.util.find_spec(trueName)
                else:
                    origSpec = _find_spec(
                        trueName,
                        sys.modules[__class__.marker +
                                    ".".join(trueNameComponents[:-1])].__path__
                    )  # should not trigger loading, since worked aroung. Workaround is needed not only here, so we cannot remove it
                    #origSpec = None # if it is a submodule we don't search for a spec, it triggers executing
            except:
                if not self.failImmediately:
                    origSpec = None
                else:
                    raise

            if origSpec:
                spec = importlib.machinery.ModuleSpec(
                    name=fullName,
                    loader=self,
                    origin=origSpec.origin,
                    loader_state=None,
                )
                spec.submodule_search_locations = origSpec.submodule_search_locations
            else:
                if self.failImmediately:
                    raise ImportError(
                        "Could not import `" + trueName +
                        "`: `origSpec` is None, which may mean there is no such a module"
                    )
                else:
                    spec = importlib.machinery.ModuleSpec(
                        name=fullName,
                        loader=self,
                    )

            spec.has_location = False
            spec.trueName = trueName
            return spec
Esempio n. 4
0
    def _find_deep_spec(name, path):
        steps = name.split('.')

        path = None

        for i in range(len(steps)):
            modname = '.'.join(steps[:i + 1])
            spec = _find_spec(modname, path)

            if spec is None:
                return None
            else:
                path = spec.submodule_search_locations

        return spec
Esempio n. 5
0
def reload(module: ModuleType,
           additionalSearchDict: Dict[str, ModuleType] = None):
    """
	Reload the module and return it.

	The module must have been successfully imported before.

	:param module: The module to reload
	:param additionalSearchDict: An additional search path to use alongside sys.modules
	:return: The module
	"""
    if not module or not isinstance(module, ModuleType):
        raise TypeError("module argument must be a ModuleType instance")
    try:
        name = module.__spec__.name
    except AttributeError:
        name = module.__name__

    if additionalSearchDict is None:
        additionalSearchDict = {}

    useCustom = module in additionalSearchDict.values()

    if useCustom:
        if additionalSearchDict.get(name) is not module:
            msg = "module {} not found in sys.modules or in additional search dict"
            raise ImportError(msg.format(name), name=name)
    else:
        if sys.modules.get(name) is not module:
            msg = "module {} not found in sys.modules or in additional search dict"
            raise ImportError(msg.format(name), name=name)

    # remove all events listeners of this module
    EventSystem.INSTANCE.removeListeners(module.__name__)

    if name in _RELOADING:
        return _RELOADING[name]
    _RELOADING[name] = module
    try:
        parent_name = name.rpartition('.')[0]
        if parent_name:
            try:
                parent = additionalSearchDict[parent_name]
            except KeyError:
                try:
                    parent = sys.modules[parent_name]
                except KeyError:
                    msg = "parent {!r} not in sys.modules nor in additional search dict"
                    raise ImportError(msg.format(parent_name),
                                      name=parent_name) from None
                else:
                    pkgpath = parent.__path__
            else:
                pkgpath = parent.__path__
        else:
            pkgpath = None
        target = module
        spec = module.__spec__ = _bootstrap._find_spec(name, pkgpath, target)
        if spec is None:
            raise ModuleNotFoundError(
                f"spec not found for the module {name!r}", name=name)
        _bootstrap._exec(spec, module)
        # The module may have replaced itself in sys.modules!
        return additionalSearchDict[name] if useCustom else sys.modules[name]
    finally:
        try:
            del _RELOADING[name]
        except KeyError:
            pass