Re: [PATCH v3 07/15] devicetree: Add DeviceTree live tree representation

From: Doug Anderson

Date: Fri Nov 06 2026 - 21:45:37 EST


Hi Simon,

On Wed, Nov 4, 2026 at 6:08 AM Simon Glass <sjg@xxxxxxxxxxxx> wrote:
>
> Hi Doug,
>
> On Sun, Nov 1, 2026 at 4:02 PM Douglas Anderson <dianders@xxxxxxxxxxxx> wrote:
> >
> > Add `devicetree.py` providing `DeviceTree`, a non-flattened in-memory
> > representation of a devicetree node and its subtree:
>
> Please can you start with the motivation, i.e. why a live tree is
> needed and what will use it? The list below mostly repeats the
> docstrings.

Makes sense. In my draft v4 I've updated the commit message to lead
with the motivation and condensed the summary so it doesn't repeat the
docstrings:

`pylibfdt`'s `Fdt` and `FdtRo` classes operate directly on flattened
device tree blobs, where inserting or deleting nodes and properties
shifts subsequent node offsets. That works well for in-place queries and
localized edits, but makes multi-tree comparison, structural diffing,
and bottom-up tree construction (as needed by the upcoming `fdtfactor`
tool) awkward and error-prone.

Add `pylibfdt/devicetree.py` providing `DeviceTree`, an in-memory live
tree representation where each node holds `props` (a dict mapping
property name to `libfdt.Property`) and `children` (a dict mapping child
node name to child `DeviceTree`), along with `unflatten()` and
`flatten()` to convert between `FdtRo`/`Fdt` blobs and live trees, and
helpers for path lookup, node creation, and pre-order traversal.

Add unit tests in `tests/devicetree_tests.py` covering `DeviceTree`
round-tripping, subtree unflattening, duplicate-name and corrupt-tree
rejection, and navigation helpers.

> > diff --git a/devicetree.py b/devicetree.py
> > new file mode 100644
> > index 0000000..f81b8fc
> > --- /dev/null
> > +++ b/devicetree.py
> > @@ -0,0 +1,226 @@
> > +# SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
> > +"""devicetree - Non-flattened in-memory device tree representation in Python."""
>
> I'd forgotten about this but PyPI has Zephyr's python-devicetree
> [1][2], which installs a top-level 'devicetree' package.
>
> I'm not sure what to suggest. Would libfdt_devicetree be too awful?

Right. I'm OK with libfdt_devicetree. David: do you have any objections?


> > + @classmethod
> > + def unflatten(cls, fdt, offset=0):
> > + """Unflatten an FdtRo subtree starting at `offset` into a DeviceTree.
> > +
> > + Args:
> > + fdt: An `FdtRo` (or `Fdt`) instance.
> > + offset: Starting node offset (default 0 for the root node).
> > +
> > + Returns:
> > + A `DeviceTree` representing the node at `offset` and its
> > + descendants.
> > +
> > + Raises:
> > + ValueError: If a node contains duplicate property names or
> > + duplicate sibling subnode names.
> > + """
> > + node = cls()
> > + for prop in fdt.properties(offset):
> > + if prop.name in node.props:
> > + raise ValueError(f'Duplicate property {prop.name!r}')
> > + node.props[prop.name] = prop
> > + for suboff in fdt.subnodes(offset):
> > + subname = fdt.get_name(suboff)
>
> We should try to stop on a corrupt tree - so I think this needs error-checking.

In my draft v4, I've rewritten `unflatten()` to a single pass and the new
implementation should catch this. I've also added a `testCorruptTree()` unit
test in `tests/devicetree_tests.py` to verify this.


-Doug