From a7ff09276cbfe1d50d0faf81cfa135bff7ef0150 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 14 May 2024 13:57:44 +0000 Subject: [PATCH] Fix RecursionError in `infer_call_result()` (#2432) (#2436) (cherry picked from commit d1c37a90359e6a8e40b9772258d0049394f8294a) Co-authored-by: Jacob Walls --- ChangeLog | 3 +++ astroid/bases.py | 5 +++++ tests/test_inference.py | 12 ++++++++++++ 3 files changed, 20 insertions(+) diff --git a/ChangeLog b/ChangeLog index 6212a95e40..17e69ccb6f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -13,6 +13,9 @@ What's New in astroid 3.2.1? ============================ Release date: TBA +* Fix ``RecursionError`` in ``infer_call_result()`` for certain ``__call__`` methods. + + Closes pylint-dev/pylint#9139 What's New in astroid 3.2.0? diff --git a/astroid/bases.py b/astroid/bases.py index 4b866a6aed..4a684cf1fe 100644 --- a/astroid/bases.py +++ b/astroid/bases.py @@ -326,6 +326,11 @@ def infer_call_result( for node in self._proxied.igetattr("__call__", context): if isinstance(node, UninferableBase) or not node.callable(): continue + if isinstance(node, BaseInstance) and node._proxied is self._proxied: + inferred = True + yield node + # Prevent recursion. + continue for res in node.infer_call_result(caller, context): inferred = True yield res diff --git a/tests/test_inference.py b/tests/test_inference.py index 10fceb7b56..ec8fc71b69 100644 --- a/tests/test_inference.py +++ b/tests/test_inference.py @@ -4090,6 +4090,18 @@ class C: inferred = next(node.infer()) self.assertRaises(InferenceError, next, inferred.infer_call_result(node)) + def test_infer_call_result_same_proxied_class(self) -> None: + node = extract_node( + """ + class A: + __call__ = A() + A() #@ + """ + ) + inferred = next(node.infer()) + fully_evaluated_inference_results = list(inferred.infer_call_result(node)) + assert fully_evaluated_inference_results[0].name == "A" + def test_infer_call_result_with_metaclass(self) -> None: node = extract_node("def with_metaclass(meta, *bases): return 42") inferred = next(node.infer_call_result(caller=node))