dtlib: add type checking for DT.root
We'd like users of this API to know that DT.root is always a Node, and not an Optional[Node]. However, although DT.__init__ throws an exception if the resulting DT object would have no root node, static analysis can't tell that since the root instance attribute starts out as None during initialization, so checkers like mypy are convinced it's Optional[Node]. Since this is really OK, we'll quiet the type checker down by stashing the instance attribute in self._root instead, and providing a root property accessor that is annotated to return Node instead of Optional[Node]. We can tell mypy to ignore what looks like a potential None here to allow callers to treat the result as a Node. Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
This commit is contained in:
parent
b13b5b8b3a
commit
c6bb336bc1
1 changed files with 15 additions and 5 deletions
|
@ -723,6 +723,8 @@ class DT:
|
||||||
|
|
||||||
self._lineno = 1
|
self._lineno = 1
|
||||||
|
|
||||||
|
self._root: Optional[Node] = None
|
||||||
|
|
||||||
self._parse_dt()
|
self._parse_dt()
|
||||||
|
|
||||||
self._register_phandles()
|
self._register_phandles()
|
||||||
|
@ -731,6 +733,16 @@ class DT:
|
||||||
self._remove_unreferenced()
|
self._remove_unreferenced()
|
||||||
self._register_labels()
|
self._register_labels()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def root(self) -> Node:
|
||||||
|
"""
|
||||||
|
See the class documentation.
|
||||||
|
"""
|
||||||
|
# This is necessary because mypy can't tell that we never
|
||||||
|
# treat self._root as a non-None value until it's initialized
|
||||||
|
# properly in _parse_dt().
|
||||||
|
return self._root # type: ignore
|
||||||
|
|
||||||
def get_node(self, path):
|
def get_node(self, path):
|
||||||
"""
|
"""
|
||||||
Returns the Node instance for the node with path or alias 'path' (a
|
Returns the Node instance for the node with path or alias 'path' (a
|
||||||
|
@ -827,15 +839,13 @@ class DT:
|
||||||
self._parse_header()
|
self._parse_header()
|
||||||
self._parse_memreserves()
|
self._parse_memreserves()
|
||||||
|
|
||||||
self.root = None
|
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
tok = self._next_token()
|
tok = self._next_token()
|
||||||
|
|
||||||
if tok.val == "/":
|
if tok.val == "/":
|
||||||
# '/ { ... };', the root node
|
# '/ { ... };', the root node
|
||||||
if not self.root:
|
if not self._root:
|
||||||
self.root = Node(name="/", parent=None, dt=self)
|
self._root = Node(name="/", parent=None, dt=self)
|
||||||
self._parse_node(self.root)
|
self._parse_node(self.root)
|
||||||
|
|
||||||
elif tok.id in (_T.LABEL, _T.REF):
|
elif tok.id in (_T.LABEL, _T.REF):
|
||||||
|
@ -868,7 +878,7 @@ class DT:
|
||||||
self._expect_token(";")
|
self._expect_token(";")
|
||||||
|
|
||||||
elif tok.id == _T.EOF:
|
elif tok.id == _T.EOF:
|
||||||
if not self.root:
|
if not self._root:
|
||||||
self._parse_error("no root node defined")
|
self._parse_error("no root node defined")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue