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()
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
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)
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)