diff options
author | Jacob Walls <jacobtylerwalls@gmail.com> | 2022-05-06 09:58:18 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-05-06 15:58:18 +0200 |
commit | e7103e68a3c8bf10fdad1da7685644a1c0e16074 (patch) | |
tree | a883a1620bcb8d537e7fdfaed7993f250bb6293f /astroid/inference.py | |
parent | c2d2057ceb0e3acf6ab46d879ed0ed2a398270df (diff) | |
download | astroid-git-e7103e68a3c8bf10fdad1da7685644a1c0e16074.tar.gz |
Let `AstroidManager.clear_cache` act on other caches (#1521)
Co-authored-by: Pierre Sassoulas <pierre.sassoulas@gmail.com>
Diffstat (limited to 'astroid/inference.py')
-rw-r--r-- | astroid/inference.py | 38 |
1 files changed, 13 insertions, 25 deletions
diff --git a/astroid/inference.py b/astroid/inference.py index cd66a917..8d85664b 100644 --- a/astroid/inference.py +++ b/astroid/inference.py @@ -23,8 +23,6 @@ from typing import ( Union, ) -import wrapt - from astroid import bases, decorators, helpers, nodes, protocols, util from astroid.context import ( CallContext, @@ -1037,28 +1035,6 @@ def infer_ifexp(self, context=None): nodes.IfExp._infer = infer_ifexp # type: ignore[assignment] -# pylint: disable=dangerous-default-value -@wrapt.decorator -def _cached_generator( - func, instance: _FunctionDefT, args, kwargs, _cache={} # noqa: B006 -): - node = instance - try: - return iter(_cache[func, id(node)]) - except KeyError: - result = func(*args, **kwargs) - # Need to keep an iterator around - original, copy = itertools.tee(result) - _cache[func, id(node)] = list(copy) - return original - - -# 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. This is why we cache the result -# of the function's inference. -@_cached_generator def infer_functiondef( self: _FunctionDefT, context: Optional[InferenceContext] = None ) -> Generator[Union["Property", _FunctionDefT], None, InferenceErrorInfo]: @@ -1066,13 +1042,25 @@ def infer_functiondef( 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] + ) + prop_func = objects.Property( function=self, name=self.name, lineno=self.lineno, - parent=self.parent, + 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) |