From 83646936b71e588f0853697d4b9429df76507fda Mon Sep 17 00:00:00 2001 From: temyurchenko <44875844+temyurchenko@users.noreply.github.com> Date: Tue, 10 Sep 2024 15:32:07 -0400 Subject: [PATCH] Fix in place properties (#2553) * fix construction of in-place properties This is an example of an in-place property: `bar = property(getter)`. They just create a nameless object, not the one with the name of the getter. Thus, the name was changed to "". Furthermore, the definition of that property is not attached to any scope, as it's again nameless. it's a part of the campaign to get rid of non-module roots --- astroid/brain/brain_builtin_inference.py | 9 ++++++--- tests/brain/test_builtin.py | 11 ++++++----- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/astroid/brain/brain_builtin_inference.py b/astroid/brain/brain_builtin_inference.py index 476620bd81..c60510d0b9 100644 --- a/astroid/brain/brain_builtin_inference.py +++ b/astroid/brain/brain_builtin_inference.py @@ -645,12 +645,15 @@ def infer_property( prop_func = objects.Property( function=inferred, - name=inferred.name, + name="", lineno=node.lineno, col_offset=node.col_offset, + # ↓ semantically, the definition of the class of property isn't within + # node.frame. It's somewhere in the builtins module, but we are special + # casing it for each "property()" call, so we are making up the + # definition on the spot, ad-hoc. + parent=AstroidManager().adhoc_module, ) - # Set parent outside __init__: https://github.com/pylint-dev/astroid/issues/1490 - prop_func.parent = node prop_func.postinit( body=[], args=inferred.args, diff --git a/tests/brain/test_builtin.py b/tests/brain/test_builtin.py index cf413f16cd..6c49a80042 100644 --- a/tests/brain/test_builtin.py +++ b/tests/brain/test_builtin.py @@ -14,7 +14,7 @@ class BuiltinsTest(unittest.TestCase): def test_infer_property(self): - class_with_property = _extract_single_node( + property_assign = _extract_single_node( """ class Something: def getter(): @@ -22,14 +22,15 @@ def getter(): asd = property(getter) #@ """ ) - inferred_property = next(iter(class_with_property.value.infer())) + inferred_property = next(iter(property_assign.value.infer())) self.assertTrue(isinstance(inferred_property, objects.Property)) - class_parent = inferred_property.parent.parent.parent + class_parent = property_assign.scope() self.assertIsInstance(class_parent, nodes.ClassDef) self.assertFalse( any( - isinstance(getter, objects.Property) - for getter in class_parent.locals["getter"] + isinstance(def_, objects.Property) + for def_list in class_parent.locals.values() + for def_ in def_list ) ) self.assertTrue(hasattr(inferred_property, "args"))