diff --git a/ChangeLog b/ChangeLog index c9744b921..6e73af55b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -37,6 +37,10 @@ What's New in astroid 3.3.11? ============================= Release date: TBA +* Fix a crash when the root of a node is not a module but is unknown. + + Closes #2672 + * Fix a crash when parsing an empty arbitrary expression with ``extract_node`` (``extract_node("__()")``). Closes #2734 diff --git a/astroid/nodes/node_ng.py b/astroid/nodes/node_ng.py index dc8942b70..d3be04720 100644 --- a/astroid/nodes/node_ng.py +++ b/astroid/nodes/node_ng.py @@ -309,13 +309,13 @@ def scope(self) -> nodes.LocalsDictNodeNG: raise ParentMissingError(target=self) return self.parent.scope() - def root(self) -> nodes.Module: + def root(self) -> nodes.Module | nodes.Unknown: """Return the root node of the syntax tree. :returns: The root node. """ if not (parent := self.parent): - assert isinstance(self, nodes.Module) + assert isinstance(self, (nodes.Module, nodes.Unknown)) return self while parent.parent: diff --git a/tests/test_regrtest.py b/tests/test_regrtest.py index 5321c7e0c..b683f4db7 100644 --- a/tests/test_regrtest.py +++ b/tests/test_regrtest.py @@ -500,6 +500,21 @@ def _get_option(self, option): assert node.inferred()[0].value == "mystr" +def test_regression_root_is_not_a_module() -> None: + """Regression test for #2672.""" + node: nodes.Attribute = _extract_single_node( + textwrap.dedent( + """ + a=eval.__get__(1).__gt__ + + @a + class c: ... + """ + ) + ) + assert node.name == "c" + + def test_regression_no_crash_during_build() -> None: node: nodes.Attribute = extract_node("__()") assert node.args == []