From 8c858927f8f2d79d1670f03a592c341720127d0f Mon Sep 17 00:00:00 2001 From: Artem Yurchenko Date: Wed, 11 Sep 2024 15:49:14 -0700 Subject: [PATCH] enforce a non-None parent in build_function We also remove `add_local_node` to avoid redundancy. Instead we do the attachment to the parent scope in the constructor of `FunctionDef`. We append a node to the body of the frame when it is also the parent. If it's not a parent, then the node should belong to the "body" of the parent if it existed. An example is a definition within an "if", where the parent is the If node, but the frame is the whole module. it's a part of the campaign to get rid of non-module roots --- astroid/nodes/scoped_nodes/scoped_nodes.py | 3 +-- astroid/raw_building.py | 11 +++++------ tests/test_raw_building.py | 10 +++++----- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/astroid/nodes/scoped_nodes/scoped_nodes.py b/astroid/nodes/scoped_nodes/scoped_nodes.py index 629d524f9f..97d0641de2 100644 --- a/astroid/nodes/scoped_nodes/scoped_nodes.py +++ b/astroid/nodes/scoped_nodes/scoped_nodes.py @@ -1174,8 +1174,7 @@ def __init__( parent=parent, ) if parent and not isinstance(parent, Unknown): - frame = parent.frame() - frame.set_local(name, self) + _attach_to_parent(self, name, parent) def postinit( self, diff --git a/astroid/raw_building.py b/astroid/raw_building.py index 70113b5779..6cafadded3 100644 --- a/astroid/raw_building.py +++ b/astroid/raw_building.py @@ -132,6 +132,7 @@ def build_class( def build_function( name: str, + parent: nodes.NodeNG, args: list[str] | None = None, posonlyargs: list[str] | None = None, defaults: list[Any] | None = None, @@ -145,7 +146,7 @@ def build_function( name, lineno=0, col_offset=0, - parent=node_classes.Unknown(), + parent=parent, end_col_offset=0, end_lineno=0, ) @@ -317,8 +318,9 @@ def object_build_function( kwonly_defaults, ) = _get_args_info_from_callable(member) - func = build_function( + build_function( localname, + node, args, posonlyargs, defaults, @@ -327,8 +329,6 @@ def object_build_function( kwonlydefaults=kwonly_defaults, ) - node.add_local_node(func, localname) - def object_build_datadescriptor( node: nodes.Module | nodes.ClassDef, member: type, name: str @@ -344,8 +344,7 @@ def object_build_methoddescriptor( ) -> None: """create astroid for a living method descriptor object""" # FIXME get arguments ? - func = build_function(localname, doc=member.__doc__) - node.add_local_node(func, localname) + func = build_function(localname, node, doc=member.__doc__) _add_dunder_class(func, node, member) diff --git a/tests/test_raw_building.py b/tests/test_raw_building.py index 1325dbc3ee..b5f3a62623 100644 --- a/tests/test_raw_building.py +++ b/tests/test_raw_building.py @@ -55,28 +55,28 @@ def test_build_class(self) -> None: self.assertEqual(node.doc_node, None) def test_build_function(self) -> None: - node = build_function("MyFunction") + node = build_function("MyFunction", DUMMY_MOD) self.assertEqual(node.name, "MyFunction") self.assertEqual(node.doc_node, None) def test_build_function_args(self) -> None: args = ["myArgs1", "myArgs2"] - node = build_function("MyFunction", args) + node = build_function("MyFunction", DUMMY_MOD, args) self.assertEqual("myArgs1", node.args.args[0].name) self.assertEqual("myArgs2", node.args.args[1].name) self.assertEqual(2, len(node.args.args)) def test_build_function_defaults(self) -> None: defaults = ["defaults1", "defaults2"] - node = build_function(name="MyFunction", args=None, defaults=defaults) + node = build_function("MyFunction", DUMMY_MOD, args=None, defaults=defaults) self.assertEqual(2, len(node.args.defaults)) def test_build_function_posonlyargs(self) -> None: - node = build_function(name="MyFunction", posonlyargs=["a", "b"]) + node = build_function("MyFunction", DUMMY_MOD, posonlyargs=["a", "b"]) self.assertEqual(2, len(node.args.posonlyargs)) def test_build_function_kwonlyargs(self) -> None: - node = build_function(name="MyFunction", kwonlyargs=["a", "b"]) + node = build_function("MyFunction", DUMMY_MOD, kwonlyargs=["a", "b"]) assert len(node.args.kwonlyargs) == 2 assert node.args.kwonlyargs[0].name == "a" assert node.args.kwonlyargs[1].name == "b"