@@ -300,9 +300,13 @@ class Signed:
300300 spec_version: The TUF specification version number (semver) the
301301 metadata format adheres to.
302302 expires: The metadata expiration datetime object.
303+ known_fields: A dictionary containing the known fields(attributes). Used
304+ when filtering the known fields from all fields in order to retrieve
305+ and store the unrecognized fields. See ADR 0008 for context.
303306
304307 """
305308
309+ known_fields = ["_type" , "spec_version" , "expires" , "version" ]
306310 # NOTE: Signed is a stupid name, because this might not be signed yet, but
307311 # we keep it to match spec terminology (I often refer to this as "payload",
308312 # or "inner metadata")
@@ -319,6 +323,19 @@ def __init__(
319323 raise ValueError (f"version must be >= 0, got { version } " )
320324 self .version = version
321325
326+ @classmethod
327+ def _store_unrecognized_fields (
328+ cls , all_fields : Mapping [str , Any ]
329+ ) -> Mapping [str , Any ]:
330+ """Utility function filtering the known fields from all in order to
331+ retrieve and store the unrecognized fields."""
332+ unrecognized_fields = {}
333+ for key , value in all_fields .items ():
334+ if key not in cls .known_fields :
335+ unrecognized_fields [key ] = value
336+
337+ cls .unrecognized_fields = unrecognized_fields
338+
322339 @staticmethod
323340 def _common_fields_from_dict (signed_dict : Mapping [str , Any ]) -> list :
324341 """Returns common fields of 'Signed' instances from the passed dict
@@ -423,6 +440,8 @@ def from_dict(cls, root_dict: Mapping[str, Any]) -> "Root":
423440 consistent_snapshot = root_dict .pop ("consistent_snapshot" )
424441 keys = root_dict .pop ("keys" )
425442 roles = root_dict .pop ("roles" )
443+ cls .known_fields += ["consistent_snapshot" , "keys" , "roles" ]
444+ cls ._store_unrecognized_fields (root_dict )
426445 return cls (* common_args , consistent_snapshot , keys , roles )
427446
428447 def to_dict (self ) -> Dict [str , Any ]:
@@ -433,6 +452,7 @@ def to_dict(self) -> Dict[str, Any]:
433452 "consistent_snapshot" : self .consistent_snapshot ,
434453 "keys" : self .keys ,
435454 "roles" : self .roles ,
455+ ** self .unrecognized_fields ,
436456 }
437457 )
438458 return root_dict
@@ -495,12 +515,14 @@ def from_dict(cls, timestamp_dict: Mapping[str, Any]) -> "Timestamp":
495515 """Creates Timestamp object from its dict representation. """
496516 common_args = cls ._common_fields_from_dict (timestamp_dict )
497517 meta = timestamp_dict .pop ("meta" )
518+ cls .known_fields += ["meta" ]
519+ cls ._store_unrecognized_fields (timestamp_dict )
498520 return cls (* common_args , meta )
499521
500522 def to_dict (self ) -> Dict [str , Any ]:
501523 """Returns the dict representation of self. """
502524 timestamp_dict = self ._common_fields_to_dict ()
503- timestamp_dict .update ({"meta" : self .meta })
525+ timestamp_dict .update ({"meta" : self .meta , ** self . unrecognized_fields })
504526 return timestamp_dict
505527
506528 # Modification.
@@ -559,12 +581,14 @@ def from_dict(cls, snapshot_dict: Mapping[str, Any]) -> "Snapshot":
559581 """Creates Snapshot object from its dict representation. """
560582 common_args = cls ._common_fields_from_dict (snapshot_dict )
561583 meta = snapshot_dict .pop ("meta" )
584+ cls .known_fields += ["meta" ]
585+ cls ._store_unrecognized_fields (snapshot_dict )
562586 return cls (* common_args , meta )
563587
564588 def to_dict (self ) -> Dict [str , Any ]:
565589 """Returns the dict representation of self. """
566590 snapshot_dict = self ._common_fields_to_dict ()
567- snapshot_dict .update ({"meta" : self .meta })
591+ snapshot_dict .update ({"meta" : self .meta , ** self . unrecognized_fields })
568592 return snapshot_dict
569593
570594 # Modification.
@@ -664,6 +688,8 @@ def from_dict(cls, targets_dict: Mapping[str, Any]) -> "Targets":
664688 common_args = cls ._common_fields_from_dict (targets_dict )
665689 targets = targets_dict .pop ("targets" )
666690 delegations = targets_dict .pop ("delegations" )
691+ cls .known_fields += ["meta" , "targets" , "delegations" ]
692+ cls ._store_unrecognized_fields (targets_dict )
667693 return cls (* common_args , targets , delegations )
668694
669695 def to_dict (self ) -> Dict [str , Any ]:
@@ -673,6 +699,7 @@ def to_dict(self) -> Dict[str, Any]:
673699 {
674700 "targets" : self .targets ,
675701 "delegations" : self .delegations ,
702+ ** self .unrecognized_fields ,
676703 }
677704 )
678705 return targets_dict
0 commit comments