dts: edtlib: allow pickling/unpickling EDT objects
We have a use case for saving the EDT object to be able to open it up again later. It would be convenient to be able to do this with the pickle module from stdlib. The only thing stopping us from doing that appears to be the open reference to sys.stderr that's held the edt object even after EDT.__init__ exits. However, there doesn't seem to be a need to keep holding on to this object, and in fact it would be a little bit nicer to drop the reference in case something else (even in the same Python process that created it originally) wants the EDT object around, but might want the warn file closed if its refcount zeroes out. Just drop the reference at the end of __init__ and make EDT._warn() throw an exception if it's attempted to be used after the constructor exits. Make pickle-ability an API guarantee so we can treat any regressions as bugs going forward. Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
This commit is contained in:
parent
e05c94e334
commit
e76b7205ef
@ -150,6 +150,9 @@ class EDT:
|
||||
|
||||
bindings_dirs:
|
||||
The bindings directory paths passed to __init__()
|
||||
|
||||
The standard library's pickle module can be used to marshal and
|
||||
unmarshal EDT objects.
|
||||
"""
|
||||
def __init__(self, dts, bindings_dirs, warn_file=None,
|
||||
warn_reg_unit_address_mismatch=True,
|
||||
@ -182,8 +185,9 @@ class EDT:
|
||||
to None. This allows 'fixed-partitions' binding to match regardless
|
||||
of the bus the 'fixed-partition' is under.
|
||||
"""
|
||||
# Do this indirection with None in case sys.stderr is deliberately
|
||||
# overridden
|
||||
# Do this indirection with None in case sys.stderr is
|
||||
# deliberately overridden. We'll only hold on to this file
|
||||
# while we're initializing.
|
||||
self._warn_file = sys.stderr if warn_file is None else warn_file
|
||||
|
||||
self._warn_reg_unit_address_mismatch = warn_reg_unit_address_mismatch
|
||||
@ -202,6 +206,11 @@ class EDT:
|
||||
|
||||
self._define_order()
|
||||
|
||||
# Drop the reference to the open warn file. This is necessary
|
||||
# to make this object pickleable, but also allows it to get
|
||||
# garbage collected and closed if nobody else is using it.
|
||||
self._warn_file = None
|
||||
|
||||
def get_node(self, path):
|
||||
"""
|
||||
Returns the Node at the DT path or alias 'path'. Raises EDTError if the
|
||||
@ -748,7 +757,10 @@ class EDT:
|
||||
.format(binding_path, prop_name))
|
||||
|
||||
def _warn(self, msg):
|
||||
print("warning: " + msg, file=self._warn_file)
|
||||
if self._warn_file is not None:
|
||||
print("warning: " + msg, file=self._warn_file)
|
||||
else:
|
||||
raise _err("can't _warn() outside of EDT.__init__")
|
||||
|
||||
|
||||
class Node:
|
||||
|
||||
Loading…
Reference in New Issue
Block a user