summaryrefslogtreecommitdiff
path: root/astroid/inference.py
diff options
context:
space:
mode:
authorJacob Walls <jacobtylerwalls@gmail.com>2022-05-06 09:58:18 -0400
committerGitHub <noreply@github.com>2022-05-06 15:58:18 +0200
commite7103e68a3c8bf10fdad1da7685644a1c0e16074 (patch)
treea883a1620bcb8d537e7fdfaed7993f250bb6293f /astroid/inference.py
parentc2d2057ceb0e3acf6ab46d879ed0ed2a398270df (diff)
downloadastroid-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.py38
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)