From a2d847089d1987c76d24738bb975e0af93404eec Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 9 Jul 2024 01:58:09 +0000 Subject: [PATCH] Fix AssertionError when inferring a property consisting of a partial function. (#2458) (#2460) Closes pylint-dev/pylint#9214 Thanks Martin Belanger for the report and Bryce Guinta for the test case. (cherry picked from commit 0f9dfa6ba8e10fe46494797989711e853323f222) Co-authored-by: Jacob Walls --- ChangeLog | 4 ++++ astroid/nodes/scoped_nodes/scoped_nodes.py | 4 ++++ tests/test_regrtest.py | 19 +++++++++++++++++++ 3 files changed, 27 insertions(+) diff --git a/ChangeLog b/ChangeLog index 66dd914c73..07071df8b7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -13,6 +13,10 @@ What's New in astroid 3.2.3? ============================ Release date: TBA +* Fix ``AssertionError`` when inferring a property consisting of a partial function. + +Closes pylint-dev/pylint#9214 + What's New in astroid 3.2.2? diff --git a/astroid/nodes/scoped_nodes/scoped_nodes.py b/astroid/nodes/scoped_nodes/scoped_nodes.py index 42de1af2d2..dc48a43c71 100644 --- a/astroid/nodes/scoped_nodes/scoped_nodes.py +++ b/astroid/nodes/scoped_nodes/scoped_nodes.py @@ -2539,6 +2539,10 @@ def igetattr( elif isinstance(inferred, objects.Property): function = inferred.function if not class_context: + if not context.callcontext: + context.callcontext = CallContext( + args=function.args.arguments, callee=function + ) # Through an instance so we can solve the property yield from function.infer_call_result( caller=self, context=context diff --git a/tests/test_regrtest.py b/tests/test_regrtest.py index 45f241f8cf..101e1d4417 100644 --- a/tests/test_regrtest.py +++ b/tests/test_regrtest.py @@ -477,3 +477,22 @@ def test_recursion_during_inference(mocked) -> None: with pytest.raises(InferenceError) as error: next(node.infer()) assert error.value.message.startswith("RecursionError raised") + + +def test_regression_missing_callcontext() -> None: + node: nodes.Attribute = _extract_single_node( + textwrap.dedent( + """ + import functools + + class MockClass: + def _get_option(self, option): + return "mystr" + + enabled = property(functools.partial(_get_option, option='myopt')) + + MockClass().enabled + """ + ) + ) + assert node.inferred()[0].value == "mystr"