Exemplo n.º 1
0
def _six_fail_hook(modname):
    """Fix six.moves imports due to the dynamic nature of this
    class.

    Construct a pseudo-module which contains all the necessary imports
    for six

    :param modname: Name of failed module
    :type modname: str

    :return: An astroid module
    :rtype: nodes.Module
    """

    attribute_of = modname != "six.moves" and modname.startswith("six.moves")
    if modname != "six.moves" and not attribute_of:
        raise AstroidBuildingError(modname=modname)
    module = AstroidBuilder(MANAGER).string_build(_IMPORTS)
    module.name = "six.moves"
    if attribute_of:
        # Facilitate import of submodules in Moves
        start_index = len(module.name)
        attribute = modname[start_index:].lstrip(".").replace(".", "_")
        try:
            import_attr = module.getattr(attribute)[0]
        except AttributeInferenceError as exc:
            raise AstroidBuildingError(modname=modname) from exc
        if isinstance(import_attr, nodes.Import):
            submodule = MANAGER.ast_from_module_name(import_attr.names[0][0])
            return submodule
    # Let dummy submodule imports pass through
    # This will cause an Uninferable result, which is okay
    return module
Exemplo n.º 2
0
def _import_gi_module(modname):
    # we only consider gi.repository submodules
    if not modname.startswith("gi.repository."):
        raise AstroidBuildingError(modname=modname)
    # build astroid representation unless we already tried so
    if modname not in _inspected_modules:
        modnames = [modname]
        optional_modnames = []

        # GLib and GObject may have some special case handling
        # in pygobject that we need to cope with. However at
        # least as of pygobject3-3.13.91 the _glib module doesn't
        # exist anymore, so if treat these modules as optional.
        if modname == "gi.repository.GLib":
            optional_modnames.append("gi._glib")
        elif modname == "gi.repository.GObject":
            optional_modnames.append("gi._gobject")

        try:
            modcode = ""
            for m in itertools.chain(modnames, optional_modnames):
                try:
                    with warnings.catch_warnings():
                        # Just inspecting the code can raise gi deprecation
                        # warnings, so ignore them.
                        try:
                            from gi import (  # pylint:disable=import-error
                                PyGIDeprecationWarning, PyGIWarning,
                            )

                            warnings.simplefilter("ignore",
                                                  PyGIDeprecationWarning)
                            warnings.simplefilter("ignore", PyGIWarning)
                        except Exception:  # pylint:disable=broad-except
                            pass

                        __import__(m)
                        modcode += _gi_build_stub(sys.modules[m])
                except ImportError:
                    if m not in optional_modnames:
                        raise
        except ImportError:
            astng = _inspected_modules[modname] = None
        else:
            astng = AstroidBuilder(AstroidManager()).string_build(
                modcode, modname)
            _inspected_modules[modname] = astng
    else:
        astng = _inspected_modules[modname]
    if astng is None:
        raise AstroidBuildingError(modname=modname)
    return astng
Exemplo n.º 3
0
    def ast_from_file(self,
                      filepath,
                      modname=None,
                      fallback=True,
                      source=False):
        """given a module name, return the astroid object"""
        try:
            filepath = get_source_file(filepath, include_no_ext=True)
            source = True
        except NoSourceFile:
            pass
        if modname is None:
            try:
                modname = ".".join(modpath_from_file(filepath))
            except ImportError:
                modname = filepath
        if (modname in self.astroid_cache
                and self.astroid_cache[modname].file == filepath):
            return self.astroid_cache[modname]
        if source:
            # pylint: disable=import-outside-toplevel; circular import
            from astroid.builder import AstroidBuilder

            return AstroidBuilder(self).file_build(filepath, modname)
        if fallback and modname:
            return self.ast_from_module_name(modname)
        raise AstroidBuildingError("Unable to build an AST for {path}.",
                                   path=filepath)
Exemplo n.º 4
0
 def infer_ast_from_something(self, obj, context=None):
     """infer astroid for the given class"""
     if hasattr(obj, "__class__") and not isinstance(obj, type):
         klass = obj.__class__
     else:
         klass = obj
     try:
         modname = klass.__module__
     except AttributeError as exc:
         raise AstroidBuildingError(
             "Unable to get module for {class_repr}.",
             cls=klass,
             class_repr=safe_repr(klass),
         ) from exc
     except Exception as exc:
         raise AstroidImportError(
             "Unexpected error while retrieving module for {class_repr}:\n"
             "{error}",
             cls=klass,
             class_repr=safe_repr(klass),
         ) from exc
     try:
         name = klass.__name__
     except AttributeError as exc:
         raise AstroidBuildingError(
             "Unable to get name for {class_repr}:\n",
             cls=klass,
             class_repr=safe_repr(klass),
         ) from exc
     except Exception as exc:
         raise AstroidImportError(
             "Unexpected error while retrieving name for {class_repr}:\n"
             "{error}",
             cls=klass,
             class_repr=safe_repr(klass),
         ) from exc
     # take care, on living object __module__ is regularly wrong :(
     modastroid = self.ast_from_module_name(modname)
     if klass is obj:
         for inferred in modastroid.igetattr(name, context):
             yield inferred
     else:
         for inferred in modastroid.igetattr(name, context):
             yield inferred.instantiate_class()
Exemplo n.º 5
0
 def ast_from_class(self, klass, modname=None):
     """get astroid for the given class"""
     if modname is None:
         try:
             modname = klass.__module__
         except AttributeError as exc:
             raise AstroidBuildingError(
                 "Unable to get module for class {class_name}.",
                 cls=klass,
                 class_repr=safe_repr(klass),
                 modname=modname,
             ) from exc
     modastroid = self.ast_from_module_name(modname)
     return modastroid.getattr(klass.__name__)[0]  # XXX
Exemplo n.º 6
0
    def file_build(self, path, modname=None):
        """Build astroid from a source code file (i.e. from an ast)

        *path* is expected to be a python source file
        """
        try:
            stream, encoding, data = open_source_file(path)
        except OSError as exc:
            raise AstroidBuildingError(
                "Unable to load file {path}:\n{error}",
                modname=modname,
                path=path,
                error=exc,
            ) from exc
        except (SyntaxError, LookupError) as exc:
            raise AstroidSyntaxError(
                "Python 3 encoding specification error or unknown encoding:\n"
                "{error}",
                modname=modname,
                path=path,
                error=exc,
            ) from exc
        except UnicodeError as exc:  # wrong encoding
            # detect_encoding returns utf-8 if no encoding specified
            raise AstroidBuildingError(
                "Wrong or no encoding specified for {filename}.",
                filename=path) from exc
        with stream:
            # get module name if necessary
            if modname is None:
                try:
                    modname = ".".join(modutils.modpath_from_file(path))
                except ImportError:
                    modname = os.path.splitext(os.path.basename(path))[0]
            # build astroid representation
            module = self._data_build(data, modname, path)
            return self._post_build(module, encoding)
Exemplo n.º 7
0
        def hook(modname: str):
            if modname == "foo.bar":
                return unittest

            raise AstroidBuildingError()
Exemplo n.º 8
0
def _six_fail_hook(modname):
    if modname != 'six.moves':
        raise AstroidBuildingError(modname=modname)
    module = AstroidBuilder(MANAGER).string_build(_IMPORTS)
    module.name = 'six.moves'
    return module