From 27bfff3736c950e9d874d04dfd3d0466eea32bc3 Mon Sep 17 00:00:00 2001 From: Artem Yurchenko Date: Tue, 3 Sep 2024 16:19:42 -0700 Subject: [PATCH] be honest that non-Module root is possible; return None in such cases The nodes are often created in an ad-hoc way, and their parent is not always set. We can't control for that invariant in the constructor, since the parent is usually set outside of the constructor. So, let's just be honest that we might not have Module as the root. --- astroid/nodes/node_ng.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/astroid/nodes/node_ng.py b/astroid/nodes/node_ng.py index 3a482f3cc..7b68d4d5e 100644 --- a/astroid/nodes/node_ng.py +++ b/astroid/nodes/node_ng.py @@ -21,7 +21,7 @@ overload, ) -from astroid import util +from astroid import nodes, util from astroid.context import InferenceContext from astroid.exceptions import ( AstroidError, @@ -326,17 +326,18 @@ def scope(self) -> nodes.LocalsDictNodeNG: raise ParentMissingError(target=self) return self.parent.scope() - def root(self) -> nodes.Module: + def root(self) -> nodes.Module | None: """Return the root node of the syntax tree. - :returns: The root node. + :returns: The root node. Might be None, if the node has been + created ad-hoc, e.g. with nodes.const_factory """ if not (parent := self.parent): - return self # type: ignore[return-value] # Only 'Module' does not have a parent node. + return self if isinstance(self, nodes.Module) else None while parent.parent: parent = parent.parent - return parent # type: ignore[return-value] # Only 'Module' does not have a parent node. + return parent if isinstance(parent, nodes.Module) else None def child_sequence(self, child): """Search for the sequence that contains this child.