def getattr(self, name, context=None): """this method doesn't look in the instance_attrs dictionary since it's done by an Instance proxy at inference time. It may return a YES object if the attribute has not been actually found but a __getattr__ or __getattribute__ method is defined """ values = self.locals.get(name, []) if name in self.special_attributes: if name == '__module__': return [cf(self.root().qname())] + values # FIXME: do we really need the actual list of ancestors? # returning [Tuple()] + values don't break any test # this is ticket http://www.logilab.org/ticket/52785 # XXX need proper meta class handling + MRO implementation if name == '__bases__' or (name == '__mro__' and self.newstyle): node = Tuple() node.items = self.ancestors(recurs=True, context=context) return [node] + values return std_special_attributes(self, name) # don't modify the list in self.locals! values = list(values) for classnode in self.ancestors(recurs=True, context=context): values += classnode.locals.get(name, []) if not values: raise NotFoundError(name) return values
def getattr(self, name, context=None, ignore_locals=False): if name in self.special_attributes: if name == '__file__': return [cf(self.file)] + self.locals.get(name, []) if name == '__path__' and self.package: return [List()] + self.locals.get(name, []) return std_special_attributes(self, name) if not ignore_locals and name in self.locals: return self.locals[name] if self.package: try: return [self.import_module(name, relative_only=True)] except AstroidBuildingException: raise NotFoundError(name) except Exception:# XXX pylint tests never pass here; do we need it? import traceback traceback.print_exc() raise NotFoundError(name)
def real_name(self, asname): """get name from 'as' name""" for name, _asname in self.names: if name == '*': return asname if not _asname: name = name.split('.', 1)[0] _asname = name if asname == _asname: return name raise NotFoundError(asname)
def std_special_attributes(self, name, add_locals=True): if add_locals: locals = self.locals else: locals = {} if name == '__name__': return [cf(self.name)] + locals.get(name, []) if name == '__doc__': return [cf(self.doc)] + locals.get(name, []) if name == '__dict__': return [Dict()] + locals.get(name, []) raise NotFoundError(name)
def instance_attr(self, name, context=None): """return the astroid nodes associated to name in this class instance attributes dictionary and in its parents :raises `NotFoundError`: if no attribute with this name has been find in this class or its parent classes """ values = self.instance_attrs.get(name, []) # get all values from parents for class_node in self.instance_attr_ancestors(name, context): values += class_node.instance_attrs[name] if not values: raise NotFoundError(name) return values
def local_attr(self, name, context=None): """return the list of assign node associated to name in this class locals or in its parents :raises `NotFoundError`: if no attribute with this name has been find in this class or its parent classes """ try: return self.locals[name] except KeyError: # get if from the first parent implementing it if any for class_node in self.local_attr_ancestors(name, context): return class_node.locals[name] raise NotFoundError(name)
def instance_attr(self, name, context=None): """return the astroid nodes associated to name in this class instance attributes dictionary and in its parents :raises `NotFoundError`: if no attribute with this name has been find in this class or its parent classes """ # Return a copy, so we don't modify self.instance_attrs, # which could lead to infinite loop. values = list(self.instance_attrs.get(name, [])) # get all values from parents for class_node in self.instance_attr_ancestors(name, context): values += class_node.instance_attrs[name] if not values: raise NotFoundError(name) return values
def igetattr(self, name, context=None): """Retrieve the inferred values of the given attribute name.""" local_name = self._model.get(name) if local_name: yield local_name return try: mro = self.super_mro() except (MroError, SuperError) as exc: # Don't let invalid MROs or invalid super calls # to leak out as is from this function. six.raise_from(NotFoundError, exc) found = False for cls in mro: if name not in cls._locals: continue found = True for infered in _infer_stmts([cls[name]], context, frame=self): if not isinstance(infered, FunctionDef): yield infered continue # We can obtain different descriptors from a super depending # on what we are accessing and where the super call is. if infered.type == 'classmethod': yield BoundMethod(infered, cls) elif self._scope.type == 'classmethod' and infered.type == 'method': yield infered elif self._class_based or infered.type == 'staticmethod': yield infered elif _is_property(infered): # TODO: support other descriptors as well. for value in infered.infer_call_result(self, context): yield value else: yield BoundMethod(infered, cls) if not found: raise NotFoundError(name)
def getattr(self, name, context=None, lookupclass=True): try: values = self._proxied.instance_attr(name, context) except NotFoundError: if name == '__class__': return [self._proxied] if lookupclass: # class attributes not available through the instance # unless they are explicitly defined if name in ('__name__', '__bases__', '__mro__', '__subclasses__'): return self._proxied.local_attr(name) return self._proxied.getattr(name, context) raise NotFoundError(name) # since we've no context information, return matching class members as # well if lookupclass: try: return values + self._proxied.getattr(name, context) except NotFoundError: pass return values
def wrapper(*args, **kwargs): nodes = [n for n in func(*args, **kwargs) if not isinstance(n, cls)] if not nodes: raise NotFoundError() return nodes