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: msg = 'Unable to get module for %s' % safe_repr(klass) raise exceptions.AstroidBuildingException(msg) except Exception as ex: msg = ('Unexpected error while retrieving module for %s: %s' % (safe_repr(klass), ex)) raise exceptions.AstroidBuildingException(msg) try: name = klass.__name__ except AttributeError: msg = 'Unable to get name for %s' % safe_repr(klass) raise exceptions.AstroidBuildingException(msg) except Exception as ex: exc = ('Unexpected error while retrieving name for %s: %s' % (safe_repr(klass), ex)) raise exceptions.AstroidBuildingException(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 ast_from_file(self, filepath, modname=None, fallback=True, source=False): """given a module name, return the astroid object""" try: filepath = modutils.get_source_file(filepath, include_no_ext=True) source = True except modutils.NoSourceFile: pass if modname is None: try: modname = '.'.join(modutils.modpath_from_file(filepath)) except ImportError: modname = filepath if modname in self.astroid_cache and self.astroid_cache[ modname].source_file == filepath: return self.astroid_cache[modname] if source: from astroid.builder import AstroidBuilder return AstroidBuilder(self).file_build(filepath, modname) elif fallback and modname: return self.ast_from_module_name(modname) raise exceptions.AstroidBuildingException( 'unable to get astroid for file %s' % filepath)
def ast_from_class(self, klass, modname=None): """get astroid for the given class""" if modname is None: try: modname = klass.__module__ except AttributeError: msg = 'Unable to get module for class %s' % safe_repr(klass) raise exceptions.AstroidBuildingException(msg) modastroid = self.ast_from_module_name(modname) return modastroid.getattr(klass.__name__)[0] # XXX
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) old_cwd = os.getcwd() if context_file: os.chdir(os.path.dirname(context_file)) try: filepath, mp_type = self.file_from_module_name( modname, context_file) if mp_type == modutils.PY_ZIPMODULE: module = self.zip_import_data(filepath) if module is not None: return module elif mp_type in (imp.C_BUILTIN, imp.C_EXTENSION): if mp_type == imp.C_EXTENSION and not self._can_load_extension( modname): return self._build_stub_module(modname) try: module = modutils.load_module_from_name(modname) except Exception as ex: msg = 'Unable to load module %s (%s)' % (modname, ex) raise exceptions.AstroidBuildingException(msg) return self.ast_from_module(module, modname) elif mp_type == imp.PY_COMPILED: msg = "Unable to load compiled module %s" % (modname, ) raise exceptions.AstroidBuildingException(msg) if filepath is None: msg = "Unable to load module %s" % (modname, ) raise exceptions.AstroidBuildingException(msg) return self.ast_from_file(filepath, modname, fallback=False) except exceptions.AstroidBuildingException as e: for hook in self._failed_import_hooks: try: return hook(modname) except exceptions.AstroidBuildingException: pass raise e finally: os.chdir(old_cwd)
def open_source_file(filename): with open(filename, 'rb') as byte_stream: encoding = detect_encoding(byte_stream.readline)[0] stream = open(filename, 'r', newline=None, encoding=encoding) try: data = stream.read() except UnicodeError: # wrong encoding # detect_encoding returns utf-8 if no encoding specified msg = 'Wrong (%s) or no encoding specified' % encoding raise exceptions.AstroidBuildingException(msg) return stream, encoding, data
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 IOError as exc: msg = 'Unable to load file %r (%s)' % (path, exc) raise exceptions.AstroidBuildingException(msg) except SyntaxError as exc: # py3k encoding specification error raise exceptions.AstroidBuildingException(exc) except LookupError as exc: # unknown encoding raise exceptions.AstroidBuildingException(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)
def file_from_module_name(self, modname, contextfile): # pylint: disable=redefined-variable-type try: value = self._mod_file_cache[(modname, contextfile)] except KeyError: try: value = modutils.file_info_from_modpath( modname.split('.'), context_file=contextfile) except ImportError as ex: msg = 'Unable to load module %s (%s)' % (modname, ex) value = exceptions.AstroidBuildingException(msg) self._mod_file_cache[(modname, contextfile)] = value if isinstance(value, exceptions.AstroidBuildingException): raise value return value
def _data_build(self, data, modname, path): """Build tree node from data and add some informations""" try: node = _parse(data + '\n') except (TypeError, ValueError, SyntaxError) as exc: raise exceptions.AstroidBuildingException(exc) if path is not None: node_file = os.path.abspath(path) else: node_file = '<?>' if modname.endswith('.__init__'): modname = modname[:-9] package = True else: package = path and path.find('__init__.py') > -1 or False builder = rebuilder.TreeRebuilder(self._manager) module = builder.visit_module(node, modname, node_file, package) module._import_from_nodes = builder._import_from_nodes module._delayed_assattr = builder._delayed_assattr return module
def hook(modname): if modname == 'foo.bar': return unittest else: raise exceptions.AstroidBuildingException()