3232import io
3333import logging
3434import tempfile
35- from datetime import datetime
35+ from datetime import datetime , timedelta
3636from typing import (
3737 IO ,
3838 Any ,
@@ -120,11 +120,11 @@ class Metadata(Generic[T]):
120120 def __init__ (
121121 self ,
122122 signed : T ,
123- signatures : Dict [str , Signature ],
123+ signatures : Optional [ Dict [str , Signature ]] = None ,
124124 unrecognized_fields : Optional [Mapping [str , Any ]] = None ,
125125 ):
126126 self .signed : T = signed
127- self .signatures = signatures
127+ self .signatures = signatures or {}
128128 self .unrecognized_fields : Mapping [str , Any ] = unrecognized_fields or {}
129129
130130 def __eq__ (self , other : Any ) -> bool :
@@ -480,11 +480,13 @@ def expires(self, value: datetime) -> None:
480480 # or "inner metadata")
481481 def __init__ (
482482 self ,
483- version : int ,
484- spec_version : str ,
485- expires : datetime ,
486- unrecognized_fields : Optional [Mapping [str , Any ]] = None ,
483+ version : Optional [ int ] ,
484+ spec_version : Optional [ str ] ,
485+ expires : Optional [ datetime ] ,
486+ unrecognized_fields : Optional [Mapping [str , Any ]],
487487 ):
488+ if spec_version is None :
489+ spec_version = "." .join (SPECIFICATION_VERSION )
488490 # Accept semver (X.Y.Z) but also X.Y for legacy compatibility
489491 spec_list = spec_version .split ("." )
490492 if len (spec_list ) not in [2 , 3 ] or not all (
@@ -497,11 +499,15 @@ def __init__(
497499 raise ValueError (f"Unsupported spec_version { spec_version } " )
498500
499501 self .spec_version = spec_version
500- self .expires = expires
501502
502- if version <= 0 :
503+ self .expires = expires or datetime .utcnow () + timedelta (days = 1 )
504+
505+ if version is None :
506+ version = 1
507+ elif version <= 0 :
503508 raise ValueError (f"version must be > 0, got { version } " )
504509 self .version = version
510+
505511 self .unrecognized_fields : Mapping [str , Any ] = unrecognized_fields or {}
506512
507513 def __eq__ (self , other : Any ) -> bool :
@@ -838,20 +844,22 @@ class Root(Signed):
838844 # pylint: disable=too-many-arguments
839845 def __init__ (
840846 self ,
841- version : int ,
842- spec_version : str ,
843- expires : datetime ,
844- keys : Dict [str , Key ],
845- roles : Mapping [str , Role ],
846- consistent_snapshot : Optional [bool ] = None ,
847+ version : Optional [ int ] = None ,
848+ spec_version : Optional [ str ] = None ,
849+ expires : Optional [ datetime ] = None ,
850+ keys : Optional [ Dict [str , Key ]] = None ,
851+ roles : Optional [ Mapping [str , Role ]] = None ,
852+ consistent_snapshot : Optional [bool ] = True ,
847853 unrecognized_fields : Optional [Mapping [str , Any ]] = None ,
848854 ):
849855 super ().__init__ (version , spec_version , expires , unrecognized_fields )
850856 self .consistent_snapshot = consistent_snapshot
851- self .keys = keys
852- if set (roles ) != TOP_LEVEL_ROLE_NAMES :
853- raise ValueError ("Role names must be the top-level metadata roles" )
857+ self .keys = keys or {}
854858
859+ if roles is None :
860+ roles = {r : Role ([], 1 ) for r in TOP_LEVEL_ROLE_NAMES }
861+ elif set (roles ) != TOP_LEVEL_ROLE_NAMES :
862+ raise ValueError ("Role names must be the top-level metadata roles" )
855863 self .roles = roles
856864
857865 def __eq__ (self , other : Any ) -> bool :
@@ -1129,14 +1137,14 @@ class Timestamp(Signed):
11291137
11301138 def __init__ (
11311139 self ,
1132- version : int ,
1133- spec_version : str ,
1134- expires : datetime ,
1135- snapshot_meta : MetaFile ,
1140+ version : Optional [ int ] = None ,
1141+ spec_version : Optional [ str ] = None ,
1142+ expires : Optional [ datetime ] = None ,
1143+ snapshot_meta : Optional [ MetaFile ] = None ,
11361144 unrecognized_fields : Optional [Mapping [str , Any ]] = None ,
11371145 ):
11381146 super ().__init__ (version , spec_version , expires , unrecognized_fields )
1139- self .snapshot_meta = snapshot_meta
1147+ self .snapshot_meta = snapshot_meta or MetaFile ( 1 )
11401148
11411149 def __eq__ (self , other : Any ) -> bool :
11421150 if not isinstance (other , Timestamp ):
@@ -1190,14 +1198,14 @@ class Snapshot(Signed):
11901198
11911199 def __init__ (
11921200 self ,
1193- version : int ,
1194- spec_version : str ,
1195- expires : datetime ,
1196- meta : Dict [str , MetaFile ],
1201+ version : Optional [ int ] = None ,
1202+ spec_version : Optional [ str ] = None ,
1203+ expires : Optional [ datetime ] = None ,
1204+ meta : Optional [ Dict [str , MetaFile ]] = None ,
11971205 unrecognized_fields : Optional [Mapping [str , Any ]] = None ,
11981206 ):
11991207 super ().__init__ (version , spec_version , expires , unrecognized_fields )
1200- self .meta = meta
1208+ self .meta = meta if meta is not None else { "targets.json" : MetaFile ( 1 )}
12011209
12021210 def __eq__ (self , other : Any ) -> bool :
12031211 if not isinstance (other , Snapshot ):
@@ -1660,15 +1668,15 @@ class Targets(Signed):
16601668 # pylint: disable=too-many-arguments
16611669 def __init__ (
16621670 self ,
1663- version : int ,
1664- spec_version : str ,
1665- expires : datetime ,
1666- targets : Dict [str , TargetFile ],
1671+ version : Optional [ int ] = None ,
1672+ spec_version : Optional [ str ] = None ,
1673+ expires : Optional [ datetime ] = None ,
1674+ targets : Optional [ Dict [str , TargetFile ]] = None ,
16671675 delegations : Optional [Delegations ] = None ,
16681676 unrecognized_fields : Optional [Mapping [str , Any ]] = None ,
16691677 ) -> None :
16701678 super ().__init__ (version , spec_version , expires , unrecognized_fields )
1671- self .targets = targets
1679+ self .targets = targets or {}
16721680 self .delegations = delegations
16731681
16741682 def __eq__ (self , other : Any ) -> bool :
0 commit comments