edtlib: make ControllerAndData a type-annotated dataclass

Converting this to a dataclass will make it easier to type annotate.
Adding type annotations is incremental progress towards type checking
the entire module.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
This commit is contained in:
Martí Bolívar 2023-04-05 14:48:29 -07:00 committed by Marti Bolivar
commit 83b6db2ec1
2 changed files with 59 additions and 47 deletions

View file

@ -771,6 +771,7 @@ class Range:
length: Optional[int]
@dataclass
class ControllerAndData:
"""
Represents an entry in an 'interrupts' or 'type: phandle-array' property
@ -802,16 +803,11 @@ class ControllerAndData:
basename:
Basename for the controller when supporting named cells
"""
def __repr__(self):
fields = []
if self.name is not None:
fields.append("name: " + self.name)
fields.append(f"controller: {self.controller}")
fields.append(f"data: {self.data}")
return "<ControllerAndData, {}>".format(", ".join(fields))
node: 'Node'
controller: 'Node'
data: dict
name: Optional[str]
basename: Optional[str]
class PinCtrl:
@ -1172,14 +1168,11 @@ class Node:
for item in _slice(self._node, "gpios", 4*n_cells,
f"4*(<#gpio-cells> (= {n_cells})"):
entry = ControllerAndData()
entry.node = self
entry.controller = self.parent
entry.data = self._named_cells(entry.controller, item, "gpio")
entry.basename = "gpio"
entry.name = None
res.append(entry)
controller = self.parent
res.append(ControllerAndData(
node=self, controller=controller,
data=self._named_cells(controller, item, "gpio"),
name=None, basename="gpio"))
return res
@ -1649,13 +1642,12 @@ class Node:
self.interrupts = []
for controller_node, data in _interrupts(node):
interrupt = ControllerAndData()
interrupt.node = self
interrupt.controller = self.edt._node2enode[controller_node]
interrupt.data = self._named_cells(interrupt.controller, data,
"interrupt")
self.interrupts.append(interrupt)
# We'll fix up the names below.
controller = self.edt._node2enode[controller_node]
self.interrupts.append(ControllerAndData(
node=self, controller=controller,
data=self._named_cells(controller, data, "interrupt"),
name=None, basename=None))
_add_names(node, "interrupt", self.interrupts)
@ -1721,14 +1713,13 @@ class Node:
_map_phandle_array_entry(prop.node, controller_node, data,
specifier_space)
entry = ControllerAndData()
entry.node = self
entry.controller = self.edt._node2enode[mapped_controller]
entry.basename = specifier_space
entry.data = self._named_cells(entry.controller, mapped_data,
specifier_space)
res.append(entry)
controller = self.edt._node2enode[mapped_controller]
# We'll fix up the names below.
res.append(ControllerAndData(
node=self, controller=controller,
data=self._named_cells(controller, mapped_data,
specifier_space),
name=None, basename=specifier_space))
_add_names(self._node, specifier_space, res)

View file

@ -61,23 +61,46 @@ def test_interrupts():
'''Tests for the interrupts property.'''
with from_here():
edt = edtlib.EDT("test.dts", ["test-bindings"])
filenames = {i: hpath(f'test-bindings/interrupt-{i}-cell.yaml')
for i in range(1, 4)}
assert str(edt.get_node("/interrupt-parent-test/node").interrupts) == \
f"[<ControllerAndData, name: foo, controller: <Node /interrupt-parent-test/controller in 'test.dts', binding {filenames[3]}>, data: {{'one': 1, 'two': 2, 'three': 3}}>, <ControllerAndData, name: bar, controller: <Node /interrupt-parent-test/controller in 'test.dts', binding {filenames[3]}>, data: {{'one': 4, 'two': 5, 'three': 6}}>]"
node = edt.get_node("/interrupt-parent-test/node")
controller = edt.get_node('/interrupt-parent-test/controller')
assert node.interrupts == [
edtlib.ControllerAndData(node=node, controller=controller, data={'one': 1, 'two': 2, 'three': 3}, name='foo', basename=None),
edtlib.ControllerAndData(node=node, controller=controller, data={'one': 4, 'two': 5, 'three': 6}, name='bar', basename=None)
]
assert str(edt.get_node("/interrupts-extended-test/node").interrupts) == \
f"[<ControllerAndData, controller: <Node /interrupts-extended-test/controller-0 in 'test.dts', binding {filenames[1]}>, data: {{'one': 1}}>, <ControllerAndData, controller: <Node /interrupts-extended-test/controller-1 in 'test.dts', binding {filenames[2]}>, data: {{'one': 2, 'two': 3}}>, <ControllerAndData, controller: <Node /interrupts-extended-test/controller-2 in 'test.dts', binding {filenames[3]}>, data: {{'one': 4, 'two': 5, 'three': 6}}>]"
node = edt.get_node("/interrupts-extended-test/node")
controller_0 = edt.get_node('/interrupts-extended-test/controller-0')
controller_1 = edt.get_node('/interrupts-extended-test/controller-1')
controller_2 = edt.get_node('/interrupts-extended-test/controller-2')
assert node.interrupts == [
edtlib.ControllerAndData(node=node, controller=controller_0, data={'one': 1}, name=None, basename=None),
edtlib.ControllerAndData(node=node, controller=controller_1, data={'one': 2, 'two': 3}, name=None, basename=None),
edtlib.ControllerAndData(node=node, controller=controller_2, data={'one': 4, 'two': 5, 'three': 6}, name=None, basename=None)
]
assert str(edt.get_node("/interrupt-map-test/node@0").interrupts) == \
f"[<ControllerAndData, controller: <Node /interrupt-map-test/controller-0 in 'test.dts', binding {filenames[1]}>, data: {{'one': 0}}>, <ControllerAndData, controller: <Node /interrupt-map-test/controller-1 in 'test.dts', binding {filenames[2]}>, data: {{'one': 0, 'two': 1}}>, <ControllerAndData, controller: <Node /interrupt-map-test/controller-2 in 'test.dts', binding {filenames[3]}>, data: {{'one': 0, 'two': 0, 'three': 2}}>]"
node = edt.get_node("/interrupt-map-test/node@0")
controller_0 = edt.get_node('/interrupt-map-test/controller-0')
controller_1 = edt.get_node('/interrupt-map-test/controller-1')
controller_2 = edt.get_node('/interrupt-map-test/controller-2')
assert str(edt.get_node("/interrupt-map-test/node@1").interrupts) == \
f"[<ControllerAndData, controller: <Node /interrupt-map-test/controller-0 in 'test.dts', binding {filenames[1]}>, data: {{'one': 3}}>, <ControllerAndData, controller: <Node /interrupt-map-test/controller-1 in 'test.dts', binding {filenames[2]}>, data: {{'one': 0, 'two': 4}}>, <ControllerAndData, controller: <Node /interrupt-map-test/controller-2 in 'test.dts', binding {filenames[3]}>, data: {{'one': 0, 'two': 0, 'three': 5}}>]"
assert node.interrupts == [
edtlib.ControllerAndData(node=node, controller=controller_0, data={'one': 0}, name=None, basename=None),
edtlib.ControllerAndData(node=node, controller=controller_1, data={'one': 0, 'two': 1}, name=None, basename=None),
edtlib.ControllerAndData(node=node, controller=controller_2, data={'one': 0, 'two': 0, 'three': 2}, name=None, basename=None)
]
assert str(edt.get_node("/interrupt-map-bitops-test/node@70000000E").interrupts) == \
f"[<ControllerAndData, controller: <Node /interrupt-map-bitops-test/controller in 'test.dts', binding {filenames[2]}>, data: {{'one': 3, 'two': 2}}>]"
node = edt.get_node("/interrupt-map-test/node@1")
assert node.interrupts == [
edtlib.ControllerAndData(node=node, controller=controller_0, data={'one': 3}, name=None, basename=None),
edtlib.ControllerAndData(node=node, controller=controller_1, data={'one': 0, 'two': 4}, name=None, basename=None),
edtlib.ControllerAndData(node=node, controller=controller_2, data={'one': 0, 'two': 0, 'three': 5}, name=None, basename=None)
]
node = edt.get_node("/interrupt-map-bitops-test/node@70000000E")
assert node.interrupts == [
edtlib.ControllerAndData(node=node, controller=edt.get_node('/interrupt-map-bitops-test/controller'), data={'one': 3, 'two': 2}, name=None, basename=None)
]
def test_ranges():
'''Tests for the ranges property'''
@ -432,8 +455,6 @@ def test_props():
'''Test Node.props (derived from DT and 'properties:' in the binding)'''
with from_here():
edt = edtlib.EDT("test.dts", ["test-bindings"])
filenames = {i: hpath(f'test-bindings/phandle-array-controller-{i}.yaml')
for i in range(0, 4)}
props_node = edt.get_node('/props')
ctrl_1, ctrl_2 = [edt.get_node(path) for path in ['/ctrl-1', '/ctrl-2']]