Exemplo n.º 1
0
    def test_path_hook_installed(self):
        # PathFinder can only use it with sys.executable on sys.path
        with patch('sys.path', sys.path):
            sys.path = [p for p in sys.path if p != sys.executable]
            PathFinder.invalidate_caches()
            self.assertIsNone(PathFinder.find_spec("pwd"))

            sys.path.append(sys.executable)
            spec = PathFinder.find_spec("pwd")
        self.assert_spec(spec,
                         "pwd",
                         is_pkg=False,
                         Loader=sys.__spec__.loader,
                         origin="built-in")
Exemplo n.º 2
0
def _find_import_match(parent_path, parent_module):
    """Attempts to find an importable module."""
    modules_paths = [parent_path] + sys.path
    found_spec = PathFinder.find_spec(parent_module, modules_paths)
    if found_spec is None:
        raise ClassNotSuitable
    return found_spec
Exemplo n.º 3
0
    def find_spec(
        self,
        fullname: str,
        path: Optional[Sequence[Union[bytes, str]]],
        target: Optional[ModuleType] = None,
    ):
        if _managers:
            index = -1
            module_spec = PathFinder.find_spec(fullname, path, target)
            if not module_spec:
                return
            module_origin = module_spec.origin
            if not module_origin:
                return
            module_path = Path(module_origin).resolve()

            while -index <= len(_managers):
                manager = _managers[index]

                if (
                    fullname in manager.plugins
                    or module_path in manager.searched_plugins.values()
                ):
                    module_spec.loader = PluginLoader(manager, fullname, module_origin)
                    return module_spec

                index -= 1
        return
Exemplo n.º 4
0
    def get_importable_spec(self, symbol_is_module=False):
        """Returns the specification of an actual importable module.

        This is a check based on the limitations that we do not
        actually perform an import, and assumes a directory structure
        with modules.

        :param symbol_is_module: if it's known that the symbol is also
                                 a module, include it in the search for
                                 an importable spec
        :type symbol_is_module: bool
        """
        modules_paths = sys.path
        modules_paths.insert(0, self.get_relative_module_fs_path())
        spec = None
        for component, previous in self._walk_importable_components(
                symbol_is_module):
            if previous:
                modules_paths = [
                    os.path.join(mod, previous) for mod in modules_paths[:]
                ]
            spec = PathFinder.find_spec(component, modules_paths)
            if spec is None:
                break
        return spec
Exemplo n.º 5
0
 def find_spec(cls, fullname, path=None, target=None):
     parts = fullname.split('.')
     if len(parts) > 2 and parts[:2] == ['eddy', 'plugins']:
         from importlib.machinery import PathFinder
         return PathFinder.find_spec(
             fullname, [os.path.join(os.path.dirname(__file__), os.pardir)],
             target)
Exemplo n.º 6
0
 def find_spec(cls, fullname, path, target=None):
     if any(fullname.startswith(rdir) for rdir in (RECIPE_DIR, CONFIG_DIR)):
         if path is None:
             path = [os.path.abspath('.')]
         elif isinstance(path, str):
             path = [os.path.abspath(os.path.join('.', path))]
         spec = PathFinder.find_spec(fullname, path, target)
         return spec
Exemplo n.º 7
0
 def find_spec(cls, fullname, path, target=None):
     for rprefix, rdir in ((gs.RECIPE_PREFIX, gs.RECIPE_PATH),
                           (gs.CONFIG_PREFIX, gs.CONFIG_PATH)):
         if fullname.startswith(rprefix):
             if path is None:
                 path = [os.path.abspath(rdir)]
             elif isinstance(path, str):
                 path = [os.path.abspath(os.path.join(rdir, path))]
             spec = PathFinder.find_spec(fullname, path, target)
             return spec
Exemplo n.º 8
0
 def find_spec(cls, fullname, path=None, target=None):
     spec = PathFinder.find_spec(fullname, path=path, target=target)
     if spec is None:
         return
     if spec.loader is not None:
         if hasattr(spec.loader, 'exec_module'):
             spec.loader = CustomLoader(spec.loader)
         else:
             spec.loader = LegacyCustomLoader(spec.loader)
     return spec
Exemplo n.º 9
0
    def find_spec(
        self,
        fullname: str,
        path: Optional[Sequence[Union[bytes, str]]] = None,
        target: Optional[types.ModuleType] = None,
    ) -> Optional[ModuleSpec]:
        if fullname != "pip":
            return None

        spec = PathFinder.find_spec(fullname, [PIP_SOURCES_ROOT], target)
        assert spec, (PIP_SOURCES_ROOT, fullname)
        return spec
Exemplo n.º 10
0
    def find_spec(cls, fullname: str, path=None, target=None):
        """Try to find a spec for 'fullname' on sys.path or 'path'.

    Search only for modules starting with 'labs.ext.' and use PathFinder to first search for
    submodule in the current build, then module starting with labs_.
    """

        if not fullname.startswith(_prefix):
            return None  # Not a labs extension

        _name = fullname[_offset:]
        if '.' in _name:
            return None  # Extension already imported, this is a submodule.

        # Try importing non packaged version

        paths_1, paths_2 = _get_ctx_path()
        if paths_1:
            spec = PathFinder.find_spec(fullname, paths_1, target)
            if spec is not None:
                return _patch_spec(fullname,
                                   spec)  # Correct the module's name.

        # Try importing a packaged version

        installed_name = f'labs_{_name}'

        if paths_2:
            spec = PathFinder.find_spec(installed_name, paths_2, target)
            if spec is not None:
                return _patch_spec(fullname,
                                   spec)  # Correct the module's name.

        # Try importing an installed version

        spec = PathFinder.find_spec(installed_name, None, target)
        if spec is not None:
            return _patch_spec(fullname, spec)  # Correct the module's name.

        return None
Exemplo n.º 11
0
 def find_spec(self, fullname: str, path, target):
     if _manager_stack:
         index = -1
         while -index <= len(_manager_stack):
             manager = _manager_stack[index]
             newname = manager._rewrite_module_name(fullname)
             if newname:
                 spec = PathFinder.find_spec(newname,
                                             list(manager.search_path),
                                             target)
                 if spec:
                     return spec
             index -= 1
     return None
Exemplo n.º 12
0
    def find_spec(self, fullname: str, path, target):
        if _manager_stack:
            index = -1
            origin_spec = PathFinder.find_spec(fullname, path, target)
            while -index <= len(_manager_stack):
                manager = _manager_stack[index]

                rel_name = None
                if origin_spec and origin_spec.origin:
                    rel_name = manager._check_absolute_import(
                        origin_spec.origin)

                newname = manager._rewrite_module_name(rel_name or fullname)
                if newname:
                    spec = PathFinder.find_spec(
                        newname, path or [*manager.search_path, *sys.path],
                        target)
                    if spec:
                        spec.loader = PluginLoader(  # type: ignore
                            manager, newname, spec.origin)
                        return spec
                index -= 1
        return None
Exemplo n.º 13
0
def get_package_directory(module_name):
    """Return Path of the package directory that the given module is in."""
    base_module = module_name.split('.', 1)[0]
    # Find the import path of the package, excluding the `''` entry in `sys.path` so as
    # to avoid the false positive of returning the CWD if the user is in the development
    # directory (which may also be in the path for the case of an editable install,
    # which is why we skip `''` specifically, and not anything that expands to CWD).
    spec = PathFinder.find_spec(base_module, path=[p for p in sys.path if p])
    if spec is None or spec.origin is None:
        raise ModuleNotFoundError(base_module)
    if not spec.parent:
        msg = f'{base_module} is not a package'
        raise ValueError(msg)
    return Path(spec.origin).parent
Exemplo n.º 14
0
    def find_spec(self, fullname, path=None, target=None):
        if world.rank == 0:
            spec = PathFinder.find_spec(fullname, path, target)
            if spec is None:
                return None

            code = spec.loader.get_code(fullname)
            if code is None:  # C extensions
                return None

            loader = BroadcastLoader(spec, self.module_cache)
            assert fullname == spec.name

            searchloc = spec.submodule_search_locations
            spec = ModuleSpec(fullname,
                              loader,
                              origin=spec.origin,
                              is_package=searchloc is not None)
            if searchloc is not None:
                spec.submodule_search_locations += searchloc
            return spec
        else:
            if fullname not in self.module_cache:
                # Could this in principle interfere with builtin imports?
                return PathFinder.find_spec(fullname, path, target)

            searchloc, origin = self.module_cache[fullname][0]
            loader = BroadcastLoader(None, self.module_cache)
            spec = ModuleSpec(fullname,
                              loader,
                              origin=origin,
                              is_package=searchloc is not None)
            if searchloc is not None:
                spec.submodule_search_locations += searchloc
            loader.spec = spec  # XXX loader.loader is still None
            return spec
Exemplo n.º 15
0
    def find_spec(self, fullname, path, target=None):
        spec = None
        if fullname in self._soft_patches or fullname in self._hard_patches:
            spec = PathFinder.find_spec(fullname, path, target=target)
            if spec is None:
                raise Exception("Could not patch %s" % fullname)

            if fullname in self._soft_patches:
                self._wrap_soft_patches(spec.loader,
                                        self._soft_patches[fullname])
            elif fullname in self._hard_patches:
                self._wrap_hard_patch(spec.loader,
                                      self._hard_patches[fullname])

        return spec
Exemplo n.º 16
0
 def find_spec(self, fullname: str, path, target):
     if _manager_stack:
         index = -1
         while -index <= len(_manager_stack):
             manager = _manager_stack[index]
             newname = manager._rewrite_module_name(fullname)
             if newname:
                 spec = PathFinder.find_spec(
                     newname, [*manager.search_path, *(path or sys.path)],
                     target)
                 if spec:
                     spec.loader = PluginLoader(manager, newname,
                                                spec.origin)
                     return spec
             index -= 1
     return None
Exemplo n.º 17
0
    def import_plugin(self, name, additional_paths=[]):
        """ Mimics Python's import mechanism to import plugins found in the
            specified plugin directories; returns the imported plugin module
        
        Args:
            name (str): The name of the plugin's module to be imported
            additional_paths (:obj:`list`, optional): Additional paths to
                search for the plugin in
        
        Returns:
            ModuleType: The imported plugin's module
        
        Raises:
            ImportError: If the name cannot be resolved without a package
                (e.g. a relative import)
            ModuleNotFoundError: If the name cannot be found in any of the
                searched directories.
        
        """
        try:
            abs_name = importlib.util.resolve_name(name, None)
        except ImportError:
            raise ImportError(f'Invalid plugin name {name!r}')

        try:
            # if the plugin is already loaded, return it
            return self.plugins[abs_name]
        except KeyError:
            pass
        
        try:
            # if the plugin is already imported, return it
            return sys.modules[abs_name]
        except KeyError:
            pass
        
        search_paths = list(set(self.plugin_dirs + additional_paths))
        spec = PathFinder.find_spec(abs_name, search_paths)
        if not spec:
            raise ModuleNotFoundError(f'No plugin named {abs_name!r}',
                                      name=abs_name)
        
        module = importlib.util.module_from_spec(spec)
        sys.modules[abs_name] = module
        spec.loader.exec_module(module)
        self.logger.debug("Imported plugin: %s", abs_name)
        return module
Exemplo n.º 18
0
def findModules(module, submoduleName, pattern="*"):
    """Find the direct submodules from one or more DIRAC extension(s) that match a pattern

    :param list/str/module module: One or more Python modules or Python module names
    :param str submoduleName: The submodule under ``module`` in which to look
    :param str pattern: A ``fnmatch``-style pattern that the submodule must match
    :returns: list of tuples of the form (SystemName, ServiceName)
    """
    for system in _findSystems(module):
        agentModule = PathFinder.find_spec(
            submoduleName, path=system.submodule_search_locations)
        if not agentModule:
            continue
        for _, name, _ in pkgutil.iter_modules(
                agentModule.submodule_search_locations):
            if fnmatch.fnmatch(name, pattern):
                yield system.name, name
Exemplo n.º 19
0
    def find_spec(cls, fullname, path=None, target=None):
        """
        From the official documentation:
         - path is the list of paths where to look for the module,
                if set to 'None', then search for sys.path.
         - target is set only in case this is a module reload request,
                  otherwise it will always be 'None'.
        """
        splitname = fullname.split('.')

        # CHECK IF NAME MATCHES THE PLUGIN PACKAGE PATH
        if splitname[:2] == ['eddy', 'plugins'] and len(splitname) >= 3:
            if splitname[2] in PluginManager.info:
                plugin_spec, plugin_path, plugin_class = PluginManager.info.get(splitname[2])
                plugin_path = expandPath(plugin_path)
                return PathFinder.find_spec(fullname, [plugin_path])
        return None
Exemplo n.º 20
0
    def find_spec(
        self,
        fullname: str,
        path: Optional[Sequence[Union[bytes, str]]],
        target: Optional[ModuleType] = None,
    ):
        if _managers:
            module_spec = PathFinder.find_spec(fullname, path, target)
            if not module_spec:
                return
            module_origin = module_spec.origin
            if not module_origin:
                return
            module_path = Path(module_origin).resolve()

            for manager in reversed(_managers):
                # use path instead of name in case of submodule name conflict
                if (fullname in manager.plugins or module_path
                        in manager._searched_plugin_names.values()):
                    module_spec.loader = PluginLoader(manager, fullname,
                                                      module_origin)
                    return module_spec
        return
Exemplo n.º 21
0
    def find_spec(cls, fullname, path, target=None):
        for load_path in gs.IMPORT_PATHS:
            if load_path.endswith(os.path.sep):
                module_dir = load_path[:-1]
                module_prefix = ''
            else:
                module_dir = os.path.dirname(load_path)
                if not module_dir:
                    module_dir = '.'
                module_prefix = os.path.basename(load_path)

            if not module_prefix or fullname == module_prefix or fullname.startswith(
                    module_prefix + '.'):
                if path is None:
                    search_path = [os.path.abspath(module_dir)]
                elif isinstance(path, str):
                    search_path = [
                        os.path.abspath(os.path.join(module_dir, path))
                    ]
                else:
                    search_path = path
                spec = PathFinder.find_spec(fullname, search_path, target)
                if spec:
                    return spec
Exemplo n.º 22
0
def find_python_tests(module_name, class_name, determine_match, path):
    """
    Attempts to find Python tests from source files

    A Python test in this context is a method within a specific type
    of class (or that inherits from a specific class).

    :param module_name: the name of the module from which a class should
                        have come from
    :type module_name: str
    :param class_name: the name of the class that is considered to contain
                       test methods
    :type class_name: str
    :type determine_match: a callable that will determine if a given module
                           and class is contains valid Python tests
    :type determine_match: function
    :param path: path to a Python source code file
    :type path: str
    :returns: tuple where first item is dict with class name and additional
              info such as method names and tags; the second item is
              set of class names which look like Python tests but have been
              forcefully disabled.
    :rtype: tuple
    """
    module = PythonModule(path, module_name, class_name)
    # The resulting test classes
    result = collections.OrderedDict()
    disabled = set()

    for klass in module.iter_classes():
        docstring = ast.get_docstring(klass)
        # Looking for a class that has in the docstring either
        # ":avocado: enable" or ":avocado: disable
        if check_docstring_directive(docstring, 'disable'):
            disabled.add(klass.name)
            continue

        if check_docstring_directive(docstring, 'enable'):
            info = get_methods_info(klass.body,
                                    get_docstring_directives_tags(docstring),
                                    get_docstring_directives_requirements(
                                        docstring))
            result[klass.name] = info
            continue

        # From this point onwards we want to do recursive discovery, but
        # for now we don't know whether it is avocado.Test inherited
        # (Ifs are optimized for readability, not speed)

        # If "recursive" tag is specified, it is forced as test
        if check_docstring_directive(docstring, 'recursive'):
            is_valid_test = True
        else:
            is_valid_test = module.is_matching_klass(klass)
        info = get_methods_info(klass.body,
                                get_docstring_directives_tags(docstring),
                                get_docstring_directives_requirements(
                                    docstring))
        _disabled = set()

        # Getting the list of parents of the current class
        parents = klass.bases

        # Searching the parents in the same module
        for parent in parents[:]:
            # Looking for a 'class FooTest(Parent)'
            if not isinstance(parent, ast.Name):
                # 'class FooTest(bar.Bar)' not supported withing
                # a module
                continue
            parent_class = parent.id
            _info, _dis, _python_test = _examine_class(module.path,
                                                       parent_class,
                                                       is_valid_test,
                                                       module_name,
                                                       class_name,
                                                       determine_match)
            if _info:
                parents.remove(parent)
                _extend_test_list(info, _info)
                _disabled.update(_dis)
            if _python_test is not is_valid_test:
                is_valid_test = _python_test

        # If there are parents left to be discovered, they
        # might be in a different module.
        for parent in parents:
            if hasattr(parent, 'value'):
                if hasattr(parent.value, 'id'):
                    # We know 'parent.Class' or 'asparent.Class' and need
                    # to get path and original_module_name. Class is given
                    # by parent definition.
                    _parent = module.imported_objects.get(parent.value.id)
                    if _parent is None:
                        # We can't examine this parent (probably broken
                        # module)
                        continue
                    parent_path = os.path.dirname(_parent)
                    parent_module = os.path.basename(_parent)
                    parent_class = parent.attr
                else:
                    # We don't support multi-level 'parent.parent.Class'
                    continue
            else:
                # We only know 'Class' or 'AsClass' and need to get
                # path, module and original class_name
                _parent = module.imported_objects.get(parent.id)
                if _parent is None:
                    # We can't examine this parent (probably broken
                    # module)
                    continue
                parent_path, parent_module, parent_class = (
                    _parent.rsplit(os.path.sep, 2))

            modules_paths = [parent_path,
                             os.path.dirname(module.path)] + sys.path
            found_spec = PathFinder.find_spec(parent_module, modules_paths)
            if found_spec is None:
                continue
            _info, _dis, _python_test = _examine_class(found_spec.origin,
                                                       parent_class,
                                                       is_valid_test,
                                                       module_name,
                                                       class_name,
                                                       determine_match)
            if _info:
                info.extend(_info)
                _disabled.update(_dis)
            if _python_test is not is_valid_test:
                is_valid_test = _python_test

        # Only update the results if this was detected as 'avocado.Test'
        if is_valid_test:
            result[klass.name] = info
            disabled.update(_disabled)

    return result, disabled
Exemplo n.º 23
0
class CometModuleFinder(object):
    def __init__(self):
        self.patcher_functions = {}

        if sys.version_info[0] >= 3:
            from importlib.machinery import PathFinder
            self.pathfinder = PathFinder()

    def register(self, module_name, object_name, patcher_function):
        module_patchers = self.patcher_functions.setdefault(module_name, {})
        module_patchers[object_name] = patcher_function

    def start(self):
        if self not in sys.meta_path and not in_notebook_environment():
            sys.meta_path.insert(0, self)

    def find_module(self, fullname, path=None):
        """ Python 2 import hook
        """
        if fullname not in self.patcher_functions:
            return

        return self

    def load_module(self, fullname):
        """ Python 2 import hook
        """
        module = self._get_module(fullname)
        return self._patch(module, fullname)

    def find_spec(self, fullname, path=None, target=None):
        """ Python 3 import hook
        """
        if fullname not in self.patcher_functions:
            return

        from importlib.machinery import ModuleSpec, SourceFileLoader

        spec = self.pathfinder.find_spec(fullname, path, target)
        loader = SourceFileLoader(fullname, spec.origin)
        return ModuleSpec(fullname, CustomFileLoader(loader, fullname, self))

    def _get_module(self, fullname):
        splitted_name = fullname.split('.')
        parent = '.'.join(splitted_name[:-1])

        if fullname in sys.modules:
            return sys.modules[fullname]
        elif parent in sys.modules:
            parent = sys.modules[parent]
            module_path = imp.find_module(splitted_name[-1], parent.__path__)
            return imp.load_module(fullname, *module_path)
        else:
            module_path = imp.find_module(fullname)
            return imp.load_module(fullname, *module_path)

    def _patch(self, module, fullname):
        objects_to_patch = self.patcher_functions.get(fullname, {})

        for object_name, patcher_function in objects_to_patch.items():
            object_path = object_name.split('.')

            original = self._get_object(module, object_path)

            if original is None:
                # TODO: Send back the error?
                continue

            new_object = patcher_function(original)
            self._set_object(module, object_path, new_object)

        return module

    def _get_object(self, module, object_path):
        current_object = module

        for part in object_path:
            try:
                current_object = getattr(current_object, part)
            except AttributeError:
                return None

        return current_object

    def _set_object(self, module, object_path, new_object):
        object_to_patch = self._get_object(module, object_path[:-1])
        setattr(object_to_patch, object_path[-1], new_object)
Exemplo n.º 24
0
Arquivo: init.py Projeto: lez/xhpy
 def find_spec(self, name, path, target=None):
   ms = PathFinder.find_spec(name, path, target)
   if self.is_xhpy_module(name):
     ms.loader = XHPyLoader(ms.origin)
   return ms
log_message("boot_directory = %r", boot_directory)

path = list(sys.path)

if boot_directory in path:
    del path[path.index(boot_directory)]

try:
    if PY2:
        import imp

        module_spec = imp.find_module("sitecustomize", path)
    else:
        from importlib.machinery import PathFinder

        module_spec = PathFinder.find_spec("sitecustomize", path=path)

except ImportError:
    pass
else:
    if module_spec is not None:  # Import error not raised in importlib
        log_message("sitecustomize = %r", module_spec)

        if PY2:
            imp.load_module("sitecustomize", *module_spec)
        else:
            module_spec.loader.load_module("sitecustomize")

# Because the PYTHONPATH environment variable has been amended and the
# bootstrap directory added, if a Python application creates a sub
# process which runs a different Python interpreter, then it will still
Exemplo n.º 26
0
def _findSystems(module):
    """Implementation of _findSystems that returns a generator of system names"""
    for _, name, _ in pkgutil.iter_modules(module.__path__):
        if name.endswith("System"):
            yield PathFinder.find_spec(name, path=module.__path__)
Exemplo n.º 27
0
class CometModuleFinder(object):
    def __init__(self):
        self.patcher_functions = {}

        if sys.version_info[0] >= 3:
            from importlib.machinery import PathFinder

            self.pathfinder = PathFinder()

    def register_before(self,
                        module_name,
                        object_name,
                        patcher_function,
                        allow_empty_experiment=False):
        self._register("before", module_name, object_name, patcher_function,
                       allow_empty_experiment)

    def register_after(self,
                       module_name,
                       object_name,
                       patcher_function,
                       allow_empty_experiment=False):
        self._register("after", module_name, object_name, patcher_function,
                       allow_empty_experiment)

    def _register(
        self,
        lifecycle,
        module_name,
        object_name,
        patcher_function,
        allow_empty_experiment,
    ):
        module_patchers = self.patcher_functions.setdefault(module_name, {})
        object_patchers = module_patchers.setdefault(
            object_name,
            {
                "before": [],
                "after": [],
                "allow_empty_experiment": allow_empty_experiment,
            },
        )
        object_patchers[lifecycle].append(patcher_function)

    def start(self):
        if self not in sys.meta_path:
            sys.meta_path.insert(0, self)

    def find_module(self, fullname, path=None):
        """ Python 2 import hook
        """
        if fullname not in self.patcher_functions:
            return

        return self

    def load_module(self, fullname):
        """ Python 2 import hook
        """
        module = self._get_module(fullname)
        return self._patch(module, fullname)

    def find_spec(self, fullname, path=None, target=None):
        """ Python 3 import hook
        """
        if fullname not in self.patcher_functions:
            return

        spec = self.pathfinder.find_spec(fullname, path, target)

        if not spec:
            return

        new_loader = CustomFileLoader(spec.loader, fullname, self)
        spec.loader = new_loader

        return spec

    def _get_module(self, fullname):
        splitted_name = fullname.split(".")
        parent = ".".join(splitted_name[:-1])

        if fullname in sys.modules:
            return sys.modules[fullname]

        elif parent in sys.modules:
            parent = sys.modules[parent]
            module_path = imp.find_module(splitted_name[-1], parent.__path__)
            return imp.load_module(fullname, *module_path)

        else:
            try:
                module_path = imp.find_module(fullname)
                return imp.load_module(fullname, *module_path)

            except ImportError:
                for p in sys.path:
                    importer = get_pep_302_importer(p)

                    # Ignore invalid paths
                    if importer is None:
                        continue

                    module_path = importer.find_module(fullname)

                    if module_path:
                        return importer.load_module(fullname)

    def _patch(self, module, fullname):
        objects_to_patch = self.patcher_functions.get(fullname, {})

        for object_name, patcher_callbacks in objects_to_patch.items():
            object_path = object_name.split(".")

            original = self._get_object(module, object_path)

            if original is None:
                # TODO: Send back the error?
                continue

            new_object = Entrypoint(original, **patcher_callbacks)
            self._set_object(module, object_path, original, new_object)

        return module

    def _get_object(self, module, object_path):
        current_object = module

        for part in object_path:
            try:
                current_object = getattr(current_object, part)
            except AttributeError:
                return None

        return current_object

    def _set_object(self, module, object_path, original, new_object):
        object_to_patch = self._get_object(module, object_path[:-1])

        original_self = getattr(original, "__self__", None)

        # Support classmethod
        if original_self and inspect.isclass(original_self):
            new_object = classmethod(new_object)
            # Support staticmethod
        elif (six.PY2 and inspect.isclass(object_to_patch)
              and isinstance(original, types.FunctionType)):
            new_object = staticmethod(new_object)

        setattr(object_to_patch, object_path[-1], new_object)
Exemplo n.º 28
0
        print('ERROR:', req, repr(e))
        ret = 1
        continue

    # Try to load top level modules. This should not have any side-effects.
    try:
        metalines = dist.get_metadata_lines('top_level.txt')
    except (KeyError, EnvironmentError):
        # distutils (i.e. #:use-setuptools? #f) will not install any metadata.
        # This file is also missing for packages built using a PEP 517 builder
        # such as poetry.
        print('WARNING: cannot determine top-level modules')
        continue
    for name in metalines:
        # Only available on Python 3.
        if PathFinder and PathFinder.find_spec(name) is None:
            # Ignore unavailable modules, often C modules, which were not
            # installed at the top-level. Cannot use ModuleNotFoundError,
            # because it is raised by failed imports too.
            continue
        try:
            print('...trying to load module', name, end=': ')
            importlib.import_module(name)
            print('OK')
        except Exception:
            print('ERROR:')
            traceback.print_exc(file=sys.stdout)
            ret = 1

    # Try to load entry points of console scripts too, making sure they
    # work. They should be removed if they don't. Other groups may not be
Exemplo n.º 29
0
 def find_spec(fullname, path=None, target=None):
     "Method for Python 3.4+."
     return PathFinder.find_spec(fullname, path or _get_paths(), target)
Exemplo n.º 30
0
 def find_spec(cls, fullname, path, target=None):
     if fullname.startswith('fife'):
         return ModuleSpec(fullname, DummyLoader())
     return PathFinder.find_spec(fullname, path, target)
Exemplo n.º 31
0
def _examine_class(path, class_name, match, target_module, target_class,
                   determine_match):
    """
    Examine a class from a given path

    :param path: path to a Python source code file
    :type path: str
    :param class_name: the specific class to be found
    :type path: str
    :param match: whether the inheritance from <target_module.target_class> has
                  been determined or not
    :type match: bool
    :param target_module: the module name under which the target_class lives
    :type target_module: str
    :param target_class: the name of the class that class_name should
                         ultimately inherit from
    :type target_class: str
    :param determine_match: a callable that will determine if a match has
                            occurred or not
    :type determine_match: function
    :returns: tuple where first item is a list of test methods detected
              for given class; second item is set of class names which
              look like avocado tests but are force-disabled.
    :rtype: tuple
    """
    module = PythonModule(path, target_module, target_class)
    info = []
    disabled = set()

    for klass in module.iter_classes():
        if class_name != klass.name:
            continue

        docstring = ast.get_docstring(klass)

        if match is False:
            match = determine_match(module, klass, docstring)

        info = get_methods_info(klass.body,
                                get_docstring_directives_tags(docstring),
                                get_docstring_directives_requirements(
                                    docstring))

        # Getting the list of parents of the current class
        parents = klass.bases

        # From this point we use `_$variable` to name temporary returns
        # from method calls that are to-be-assigned/combined with the
        # existing `$variable`.

        # Searching the parents in the same module
        for parent in parents[:]:
            # Looking for a 'class FooTest(Parent)'
            if not isinstance(parent, ast.Name):
                # 'class FooTest(bar.Bar)' not supported withing
                # a module
                continue
            parent_class = parent.id
            _info, _disabled, _match = _examine_class(module.path, parent_class,
                                                      match, target_module,
                                                      target_class,
                                                      determine_match)
            if _info:
                parents.remove(parent)
                _extend_test_list(info, _info)
                disabled.update(_disabled)
            if _match is not match:
                match = _match

        # If there are parents left to be discovered, they
        # might be in a different module.
        for parent in parents:
            if hasattr(parent, 'value'):
                if hasattr(parent.value, 'id'):
                    # We know 'parent.Class' or 'asparent.Class' and need
                    # to get path and original_module_name. Class is given
                    # by parent definition.
                    _parent = module.imported_objects.get(parent.value.id)
                    if _parent is None:
                        # We can't examine this parent (probably broken
                        # module)
                        continue
                    parent_path = os.path.dirname(_parent)
                    parent_module = os.path.basename(_parent)
                    parent_class = parent.attr
                else:
                    # We don't support multi-level 'parent.parent.Class'
                    continue
            else:
                # We only know 'Class' or 'AsClass' and need to get
                # path, module and original class_name
                _parent = module.imported_objects.get(parent.id)
                if _parent is None:
                    # We can't examine this parent (probably broken
                    # module)
                    continue
                parent_path, parent_module, parent_class = (
                    _parent.rsplit(os.path.sep, 2))

            modules_paths = [parent_path,
                             os.path.dirname(module.path)] + sys.path
            found_spec = PathFinder.find_spec(parent_module, modules_paths)
            if found_spec is not None:
                _info, _disabled, _match = _examine_class(found_spec.origin,
                                                          parent_class,
                                                          match,
                                                          target_module,
                                                          target_class,
                                                          _determine_match_avocado)
            if _info:
                _extend_test_list(info, _info)
                disabled.update(_disabled)
            if _match is not match:
                match = _match

    return info, disabled, match
Exemplo n.º 32
0
 def getPath(self, fullname):
     """ Return the proper path to the module specified in fullname """
     actualName = self.getActualModuleName(fullname)
     return PathFinder.find_spec(actualName).origin
Exemplo n.º 33
0
 def find_spec(fullname, path=None, target=None):
     "Method for Python 3.4+."
     return PathFinder.find_spec(fullname, path or _get_paths(), target)
Exemplo n.º 34
0
 def find_spec(self, fullname, path, target=None):
     module_spec = PathFinder.find_spec(fullname, path, target)
     if module_spec and module_spec.has_location and self._is_in_directory(module_spec.origin):
         loader = Loader(fullname, module_spec.origin, self._transformer)
         is_package = os.path.basename(module_spec.origin).lower() == "__init__.py"
         return spec_from_loader(fullname, loader, origin=module_spec.origin, is_package=is_package)