laforge has submitted this change. ( https://gerrit.osmocom.org/c/pysim/+/37623?usp=email )
Change subject: pySim.tlv: Separate {to,from}_val_dict() from {to,from}_dict() ......................................................................
pySim.tlv: Separate {to,from}_val_dict() from {to,from}_dict()
There are some situations where we want to work with a type-name-wrapped dict that includes the type information, and others where we don't want that. The main reason is that nested IEs can only be reconstructed if we can determine the type/class of the nested IE from the dict data.
Let's explicitly offer {to,from}_val_dict() methods that work with the value-part only
Related: OS#6453 Change-Id: I81654ea54aed9e598943f41a26a57dcc3a7f10c2 --- M pySim/tlv.py 1 file changed, 47 insertions(+), 11 deletions(-)
Approvals: fixeria: Looks good to me, but someone else must approve laforge: Looks good to me, approved Jenkins Builder: Verified
diff --git a/pySim/tlv.py b/pySim/tlv.py index ed3be5d..8180fd1 100644 --- a/pySim/tlv.py +++ b/pySim/tlv.py @@ -142,25 +142,43 @@ else: return '%s(%s)' % (type(self).__name__, self.decoded)
- def to_dict(self): - """Return a JSON-serializable dict representing the [nested] IE data.""" + def to_val_dict(self): + """Return a JSON-serializable dict representing just the [nested] value portion of the IE + data. This does not include any indication of the type of 'self', so the resulting dict alone + will be insufficient ot recreate an object from it without additional type information.""" if len(self.children): - v = [x.to_dict() for x in self.children] + return [x.to_dict() for x in self.children] else: - v = self.decoded - return {camel_to_snake(type(self).__name__): v} + return self.decoded + + def from_val_dict(self, decoded): + """Set the IE internal decoded representation to data from the argument. + If this is a nested IE, the child IE instance list is re-created. + + This method is symmetrical to to_val_dict() aboe, i.e. there is no outer dict + containig the snake-reformatted type name of 'self'.""" + if self.nested_collection: + self.children = self.nested_collection.from_dict(decoded) + else: + self.children = [] + self.decoded = decoded + + def to_dict(self): + """Return a JSON-serializable dict representing the [nested] IE data. The returned + data contains an outer dict with the snake-reformatted type of 'self' and is hence + sufficient to re-create an object from it.""" + return {camel_to_snake(type(self).__name__): self.to_val_dict()}
def from_dict(self, decoded: dict): """Set the IE internal decoded representation to data from the argument. - If this is a nested IE, the child IE instance list is re-created.""" + If this is a nested IE, the child IE instance list is re-created. + + This method is symmetrical to to_dict() above, i.e. the outer dict must contain just a single + key-value pair, where the key is the snake-reformatted type name of 'self'""" expected_key_name = camel_to_snake(type(self).__name__) if not expected_key_name in decoded: raise ValueError("Dict %s doesn't contain expected key %s" % (decoded, expected_key_name)) - if self.nested_collection: - self.children = self.nested_collection.from_dict(decoded[expected_key_name]) - else: - self.children = [] - self.decoded = decoded[expected_key_name] + self.from_val_dict(decoded[expected_key_name])
def is_constructed(self): """Is this IE constructed by further nested IEs?"""