dtlib: type annotate DT fields and public methods
Now that all the other code it depends on is annotated, we can finish up the type annotation of this module in the main DT class. It's not worth it to try to annotate the private methods (the ones that begin with '_'). Most of these are low level lexing helpers that aren't particularly amenable to static type checking, because the type of a token's value is often dependent on the token ID in ways that static type annotations are not well equipped to capture. Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
This commit is contained in:
parent
c6bb336bc1
commit
8e30289b84
1 changed files with 28 additions and 14 deletions
|
@ -23,7 +23,8 @@ import os
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
import textwrap
|
import textwrap
|
||||||
from typing import Any, Dict, Iterable, List, NoReturn, Optional, Tuple
|
from typing import Any, Dict, Iterable, List, \
|
||||||
|
NamedTuple, NoReturn, Optional, Tuple, Union
|
||||||
|
|
||||||
# NOTE: tests/test_dtlib.py is the test suite for this library.
|
# NOTE: tests/test_dtlib.py is the test suite for this library.
|
||||||
|
|
||||||
|
@ -646,6 +647,20 @@ class _T(enum.IntEnum):
|
||||||
BYTE = 20
|
BYTE = 20
|
||||||
BAD = 21
|
BAD = 21
|
||||||
|
|
||||||
|
class _FileStackElt(NamedTuple):
|
||||||
|
# Used for maintaining the /include/ stack.
|
||||||
|
|
||||||
|
filename: str
|
||||||
|
lineno: int
|
||||||
|
contents: str
|
||||||
|
pos: int
|
||||||
|
|
||||||
|
_TokVal = Union[int, str]
|
||||||
|
|
||||||
|
class _Token(NamedTuple):
|
||||||
|
id: int
|
||||||
|
val: _TokVal
|
||||||
|
|
||||||
class DT:
|
class DT:
|
||||||
"""
|
"""
|
||||||
Represents a devicetree parsed from a .dts file (or from many files, if the
|
Represents a devicetree parsed from a .dts file (or from many files, if the
|
||||||
|
@ -694,7 +709,7 @@ class DT:
|
||||||
# Public interface
|
# Public interface
|
||||||
#
|
#
|
||||||
|
|
||||||
def __init__(self, filename, include_path=()):
|
def __init__(self, filename: str, include_path: Iterable[str] = ()):
|
||||||
"""
|
"""
|
||||||
Parses a DTS file to create a DT instance. Raises OSError if 'filename'
|
Parses a DTS file to create a DT instance. Raises OSError if 'filename'
|
||||||
can't be opened, and DTError for any parse errors.
|
can't be opened, and DTError for any parse errors.
|
||||||
|
@ -714,14 +729,14 @@ class DT:
|
||||||
self._file_contents = f.read()
|
self._file_contents = f.read()
|
||||||
|
|
||||||
self._tok_i = self._tok_end_i = 0
|
self._tok_i = self._tok_end_i = 0
|
||||||
self._filestack = []
|
self._filestack: List[_FileStackElt] = []
|
||||||
|
|
||||||
self.alias2node = {}
|
self.alias2node: Dict[str, Node] = {}
|
||||||
|
|
||||||
self._lexer_state = _DEFAULT
|
self._lexer_state: int = _DEFAULT
|
||||||
self._saved_token = None
|
self._saved_token: Optional[_Token] = None
|
||||||
|
|
||||||
self._lineno = 1
|
self._lineno: int = 1
|
||||||
|
|
||||||
self._root: Optional[Node] = None
|
self._root: Optional[Node] = None
|
||||||
|
|
||||||
|
@ -743,7 +758,7 @@ class DT:
|
||||||
# properly in _parse_dt().
|
# properly in _parse_dt().
|
||||||
return self._root # type: ignore
|
return self._root # type: ignore
|
||||||
|
|
||||||
def get_node(self, path):
|
def get_node(self, path: str) -> Node:
|
||||||
"""
|
"""
|
||||||
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
|
||||||
string). Raises DTError if the path or alias doesn't exist.
|
string). Raises DTError if the path or alias doesn't exist.
|
||||||
|
@ -780,7 +795,7 @@ class DT:
|
||||||
|
|
||||||
return _root_and_path_to_node(self.alias2node[alias], rest, path)
|
return _root_and_path_to_node(self.alias2node[alias], rest, path)
|
||||||
|
|
||||||
def has_node(self, path):
|
def has_node(self, path: str) -> bool:
|
||||||
"""
|
"""
|
||||||
Returns True if the path or alias 'path' exists. See Node.get_node().
|
Returns True if the path or alias 'path' exists. See Node.get_node().
|
||||||
"""
|
"""
|
||||||
|
@ -790,7 +805,7 @@ class DT:
|
||||||
except DTError:
|
except DTError:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def node_iter(self):
|
def node_iter(self) -> Iterable[Node]:
|
||||||
"""
|
"""
|
||||||
Returns a generator for iterating over all nodes in the devicetree.
|
Returns a generator for iterating over all nodes in the devicetree.
|
||||||
|
|
||||||
|
@ -1469,8 +1484,9 @@ class DT:
|
||||||
# Enters the /include/d file 'filename', remembering the position in
|
# Enters the /include/d file 'filename', remembering the position in
|
||||||
# the /include/ing file for later
|
# the /include/ing file for later
|
||||||
|
|
||||||
self._filestack.append((self.filename, self._lineno,
|
self._filestack.append(
|
||||||
self._file_contents, self._tok_end_i))
|
_FileStackElt(self.filename, self._lineno,
|
||||||
|
self._file_contents, self._tok_end_i))
|
||||||
|
|
||||||
# Handle escapes in filenames, just for completeness
|
# Handle escapes in filenames, just for completeness
|
||||||
filename = self._unescape(filename.encode("utf-8"))
|
filename = self._unescape(filename.encode("utf-8"))
|
||||||
|
@ -1897,8 +1913,6 @@ _escape_table = str.maketrans({
|
||||||
"\f": "\\f",
|
"\f": "\\f",
|
||||||
"\r": "\\r"})
|
"\r": "\\r"})
|
||||||
|
|
||||||
_Token = collections.namedtuple("Token", "id val")
|
|
||||||
|
|
||||||
# Lexer states
|
# Lexer states
|
||||||
_DEFAULT = 0
|
_DEFAULT = 0
|
||||||
_EXPECT_PROPNODENAME = 1
|
_EXPECT_PROPNODENAME = 1
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue