Esempio n. 1
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()
Esempio n. 2
0
 def file_from_module_name(self, modname, contextfile):
     try:
         value = self._mod_file_cache[(modname, contextfile)]
     except KeyError:
         try:
             value = file_info_from_modpath(modname.split("."),
                                            context_file=contextfile)
         except ImportError as e:
             value = AstroidImportError(
                 "Failed to import module {modname} with error:\n{error}.",
                 modname=modname,
                 # we remove the traceback here to save on memory usage (since these exceptions are cached)
                 error=e.with_traceback(None),
             )
         self._mod_file_cache[(modname, contextfile)] = value
     if isinstance(value, AstroidBuildingError):
         # we remove the traceback here to save on memory usage (since these exceptions are cached)
         raise value.with_traceback(None)
     return value
Esempio n. 3
0
    def ast_from_module_name(self, modname, context_file=None):
        """given a module name, return the astroid object"""
        if modname in self.astroid_cache:
            return self.astroid_cache[modname]
        if modname == "__main__":
            return self._build_stub_module(modname)
        if context_file:
            old_cwd = os.getcwd()
            os.chdir(os.path.dirname(context_file))
        try:
            found_spec = self.file_from_module_name(modname, context_file)
            if found_spec.type == spec.ModuleType.PY_ZIPMODULE:
                module = self.zip_import_data(found_spec.location)
                if module is not None:
                    return module

            elif found_spec.type in (
                    spec.ModuleType.C_BUILTIN,
                    spec.ModuleType.C_EXTENSION,
            ):
                if (found_spec.type == spec.ModuleType.C_EXTENSION
                        and not self._can_load_extension(modname)):
                    return self._build_stub_module(modname)
                try:
                    module = load_module_from_name(modname)
                except Exception as e:
                    raise AstroidImportError(
                        "Loading {modname} failed with:\n{error}",
                        modname=modname,
                        path=found_spec.location,
                    ) from e
                return self.ast_from_module(module, modname)

            elif found_spec.type == spec.ModuleType.PY_COMPILED:
                raise AstroidImportError(
                    "Unable to load compiled module {modname}.",
                    modname=modname,
                    path=found_spec.location,
                )

            elif found_spec.type == spec.ModuleType.PY_NAMESPACE:
                return self._build_namespace_module(
                    modname, found_spec.submodule_search_locations)
            elif found_spec.type == spec.ModuleType.PY_FROZEN:
                return self._build_stub_module(modname)

            if found_spec.location is None:
                raise AstroidImportError(
                    "Can't find a file for module {modname}.", modname=modname)

            return self.ast_from_file(found_spec.location,
                                      modname,
                                      fallback=False)
        except AstroidBuildingError as e:
            for hook in self._failed_import_hooks:
                try:
                    return hook(modname)
                except AstroidBuildingError:
                    pass
            raise e
        finally:
            if context_file:
                os.chdir(old_cwd)
Esempio n. 4
0
    def ast_from_module_name(
        self,
        modname: str | None,
        context_file: str | None = None,
        use_cache: bool = True,
    ) -> nodes.Module:
        """Given a module name, return the astroid object."""
        # Sometimes we don't want to use the cache. For example, when we're
        # importing a module with the same name as the file that is importing
        # we want to fallback on the import system to make sure we get the correct
        # module.
        if modname in self.astroid_cache and use_cache:
            return self.astroid_cache[modname]
        if modname == "__main__":
            return self._build_stub_module(modname)
        if context_file:
            old_cwd = os.getcwd()
            os.chdir(os.path.dirname(context_file))
        try:
            found_spec = self.file_from_module_name(modname, context_file)
            if found_spec.type == spec.ModuleType.PY_ZIPMODULE:
                module = self.zip_import_data(found_spec.location)
                if module is not None:
                    return module

            elif found_spec.type in (
                    spec.ModuleType.C_BUILTIN,
                    spec.ModuleType.C_EXTENSION,
            ):
                if (found_spec.type == spec.ModuleType.C_EXTENSION
                        and not self._can_load_extension(modname)):
                    return self._build_stub_module(modname)
                try:
                    module = load_module_from_name(modname)
                except Exception as e:
                    raise AstroidImportError(
                        "Loading {modname} failed with:\n{error}",
                        modname=modname,
                        path=found_spec.location,
                    ) from e
                return self.ast_from_module(module, modname)

            elif found_spec.type == spec.ModuleType.PY_COMPILED:
                raise AstroidImportError(
                    "Unable to load compiled module {modname}.",
                    modname=modname,
                    path=found_spec.location,
                )

            elif found_spec.type == spec.ModuleType.PY_NAMESPACE:
                return self._build_namespace_module(
                    modname, found_spec.submodule_search_locations)
            elif found_spec.type == spec.ModuleType.PY_FROZEN:
                if found_spec.location is None:
                    return self._build_stub_module(modname)
                # For stdlib frozen modules we can determine the location and
                # can therefore create a module from the source file
                return self.ast_from_file(found_spec.location,
                                          modname,
                                          fallback=False)

            if found_spec.location is None:
                raise AstroidImportError(
                    "Can't find a file for module {modname}.", modname=modname)

            return self.ast_from_file(found_spec.location,
                                      modname,
                                      fallback=False)
        except AstroidBuildingError as e:
            for hook in self._failed_import_hooks:
                try:
                    return hook(modname)
                except AstroidBuildingError:
                    pass
            raise e
        finally:
            if context_file:
                os.chdir(old_cwd)