def infer_functiondef( self: _FunctionDefT, context: InferenceContext | None = None, **kwargs: Any ) -> Generator[Property | _FunctionDefT, None, InferenceErrorInfo]: if not self.decorators or not bases._is_property(self): yield self return InferenceErrorInfo(node=self, context=context) # When inferring a property, we instantiate a new `objects.Property` object, # which in turn, because it inherits from `FunctionDef`, sets itself in the locals # of the wrapping frame. This means that every time we infer a property, the locals # are mutated with a new instance of the property. To avoid this, we detect this # scenario and avoid passing the `parent` argument to the constructor. parent_frame = self.parent.frame(future=True) property_already_in_parent_locals = self.name in parent_frame.locals and any( isinstance(val, objects.Property) for val in parent_frame.locals[self.name]) # We also don't want to pass parent if the definition is within a Try node if isinstance(self.parent, (nodes.TryExcept, nodes.TryFinally, nodes.If)): property_already_in_parent_locals = True prop_func = objects.Property( function=self, name=self.name, lineno=self.lineno, parent=self.parent if not property_already_in_parent_locals else None, col_offset=self.col_offset, ) if property_already_in_parent_locals: prop_func.parent = self.parent prop_func.postinit(body=[], args=self.args, doc_node=self.doc_node) yield prop_func return InferenceErrorInfo(node=self, context=context)
def igetattr(self, name, context=None): """Retrieve the inferred values of the given attribute name.""" if name in self.special_attributes: yield self.special_attributes.lookup(name) return try: mro = self.super_mro() # Don't let invalid MROs or invalid super calls # leak out as is from this function. except exceptions.SuperError as exc: raise exceptions.AttributeInferenceError( ('Lookup for {name} on {target!r} because super call {super!r} ' 'is invalid.'), target=self, attribute=name, context=context, super_=exc.super_) from exc except exceptions.MroError as exc: raise exceptions.AttributeInferenceError( ('Lookup for {name} on {target!r} failed because {cls!r} has an ' 'invalid MRO.'), target=self, attribute=name, context=context, mros=exc.mros, cls=exc.cls) from exc found = False for cls in mro: if name not in cls.locals: continue found = True for inferred in bases._infer_stmts([cls[name]], context, frame=self): if not isinstance(inferred, scoped_nodes.FunctionDef): yield inferred continue # We can obtain different descriptors from a super depending # on what we are accessing and where the super call is. if inferred.type == 'classmethod': yield bases.BoundMethod(inferred, cls) elif self._scope.type == 'classmethod' and inferred.type == 'method': yield inferred elif self._class_based or inferred.type == 'staticmethod': yield inferred elif bases._is_property(inferred): # TODO: support other descriptors as well. try: yield from inferred.infer_call_result(self, context) except exceptions.InferenceError: yield util.Uninferable else: yield bases.BoundMethod(inferred, cls) if not found: raise exceptions.AttributeInferenceError(target=self, attribute=name, context=context)
def igetattr(self, name, context=None): """Retrieve the inferred values of the given attribute name.""" if name in self.special_attributes: yield self.special_attributes.lookup(name) return try: mro = self.super_mro() # Don't let invalid MROs or invalid super calls # leak out as is from this function. except exceptions.SuperError as exc: util.reraise(exceptions.AttributeInferenceError( ('Lookup for {name} on {target!r} because super call {super!r} ' 'is invalid.'), target=self, attribute=name, context=context, super_=exc.super_)) except exceptions.MroError as exc: util.reraise(exceptions.AttributeInferenceError( ('Lookup for {name} on {target!r} failed because {cls!r} has an ' 'invalid MRO.'), target=self, attribute=name, context=context, mros=exc.mros, cls=exc.cls)) found = False for cls in mro: if name not in cls.locals: continue found = True for inferred in bases._infer_stmts([cls[name]], context, frame=self): if not isinstance(inferred, scoped_nodes.FunctionDef): yield inferred continue # We can obtain different descriptors from a super depending # on what we are accessing and where the super call is. if inferred.type == 'classmethod': yield bases.BoundMethod(inferred, cls) elif self._scope.type == 'classmethod' and inferred.type == 'method': yield inferred elif self._class_based or inferred.type == 'staticmethod': yield inferred elif bases._is_property(inferred): # TODO: support other descriptors as well. for value in inferred.infer_call_result(self, context): yield value else: yield bases.BoundMethod(inferred, cls) if not found: raise exceptions.AttributeInferenceError(target=self, attribute=name, context=context)
def query_functiondef(self, context=None): if not self.decorators or not bases._is_property(self): return [self] prop_func = objects.Property( function=self, name=self.name, doc=self.doc, lineno=self.lineno, parent=self.parent, col_offset=self.col_offset, ) prop_func.postinit(body=[], args=self.args) return [prop_func]
def infer_functiondef(self, context=None): if not self.decorators or not bases._is_property(self): yield self return dict(node=self, context=context) prop_func = objects.Property( function=self, name=self.name, doc=self.doc, lineno=self.lineno, parent=self.parent, col_offset=self.col_offset, ) prop_func.postinit(body=[], args=self.args) yield prop_func return dict(node=self, context=context)
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 igetattr(self, name: str, context: InferenceContext | None = None): """Retrieve the inferred values of the given attribute name.""" # '__class__' is a special attribute that should be taken directly # from the special attributes dict if name == "__class__": yield self.special_attributes.lookup(name) return try: mro = self.super_mro() # Don't let invalid MROs or invalid super calls # leak out as is from this function. except SuperError as exc: raise AttributeInferenceError( ("Lookup for {name} on {target!r} because super call {super!r} " "is invalid."), target=self, attribute=name, context=context, super_=exc.super_, ) from exc except MroError as exc: raise AttributeInferenceError( ("Lookup for {name} on {target!r} failed because {cls!r} has an " "invalid MRO."), target=self, attribute=name, context=context, mros=exc.mros, cls=exc.cls, ) from exc found = False for cls in mro: if name not in cls.locals: continue found = True for inferred in bases._infer_stmts([cls[name]], context, frame=self): if not isinstance(inferred, scoped_nodes.FunctionDef): yield inferred continue # We can obtain different descriptors from a super depending # on what we are accessing and where the super call is. if inferred.type == "classmethod": yield bases.BoundMethod(inferred, cls) elif self._scope.type == "classmethod" and inferred.type == "method": yield inferred elif self._class_based or inferred.type == "staticmethod": yield inferred elif isinstance(inferred, Property): function = inferred.function try: yield from function.infer_call_result(caller=self, context=context) except InferenceError: yield util.Uninferable elif bases._is_property(inferred): # TODO: support other descriptors as well. try: yield from inferred.infer_call_result(self, context) except InferenceError: yield util.Uninferable else: yield bases.BoundMethod(inferred, cls) # Only if we haven't found any explicit overwrites for the # attribute we look it up in the special attributes if not found and name in self.special_attributes: yield self.special_attributes.lookup(name) return if not found: raise AttributeInferenceError(target=self, attribute=name, context=context)