diff --git a/astroid/nodes/scoped_nodes/scoped_nodes.py b/astroid/nodes/scoped_nodes/scoped_nodes.py index 6b7b8de33..b5233d91d 100644 --- a/astroid/nodes/scoped_nodes/scoped_nodes.py +++ b/astroid/nodes/scoped_nodes/scoped_nodes.py @@ -178,6 +178,13 @@ def function_to_method(n, klass): return n +def _attach_to_parent(node: NodeNG, name: str, parent: NodeNG): + frame = parent.frame() + frame.set_local(name, node) + if frame is parent: + frame._append_node(node) + + class Module(LocalsDictNodeNG): """Class representing an :class:`ast.Module` node. @@ -1167,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 0c3862104..5b20b7d1b 100644 --- a/astroid/raw_building.py +++ b/astroid/raw_building.py @@ -129,6 +129,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, @@ -142,7 +143,7 @@ def build_function( name, lineno=0, col_offset=0, - parent=node_classes.Unknown(), + parent=parent, end_col_offset=0, end_lineno=0, ) @@ -314,8 +315,9 @@ def object_build_function( kwonly_defaults, ) = _get_args_info_from_callable(member) - func = build_function( + build_function( localname, + node, args, posonlyargs, defaults, @@ -324,8 +326,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 @@ -341,8 +341,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, member) diff --git a/tests/test_raw_building.py b/tests/test_raw_building.py index 951bf09d9..99834f51b 100644 --- a/tests/test_raw_building.py +++ b/tests/test_raw_building.py @@ -33,6 +33,8 @@ build_module, ) +DUMMY_MOD = build_module("DUMMY") + class RawBuildingTC(unittest.TestCase): def test_attach_dummy_node(self) -> None: @@ -53,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"