mirror of
https://github.com/theupdateframework/python-tuf
synced 2026-05-24 10:08:28 +00:00
Metadata API: Add default constructor arguments
This allows creating new metadata with less boilerplate:
root = Metadata(Root())
targets = Metadata(Targets())
Set reasonable default values for all the arguments -- version to
1, spec_version to current supported version, etc.
Expires does not have a good default value and my original plan was
to require expires argument to be set. That would mean an
incompatible API change though as arguments before expires would be
now optional... So expires now defaults to an arbitrary value of 1
day from moment of creation.
One noteworthy special case is consistent_snapshot where the default
value is True (since that's what we want people to use for new
metadata) but None is also used to imply that metadata does not contain
the field at all.
Signed-off-by: Jussi Kukkonen <jkukkonen@vmware.com>
This commit is contained in:
parent
b7b035aea1
commit
d2f8c99c19
1 changed files with 41 additions and 33 deletions
|
|
@ -32,7 +32,7 @@
|
|||
import io
|
||||
import logging
|
||||
import tempfile
|
||||
from datetime import datetime
|
||||
from datetime import datetime, timedelta
|
||||
from typing import (
|
||||
IO,
|
||||
Any,
|
||||
|
|
@ -120,11 +120,11 @@ class Metadata(Generic[T]):
|
|||
def __init__(
|
||||
self,
|
||||
signed: T,
|
||||
signatures: Dict[str, Signature],
|
||||
signatures: Optional[Dict[str, Signature]] = None,
|
||||
unrecognized_fields: Optional[Mapping[str, Any]] = None,
|
||||
):
|
||||
self.signed: T = signed
|
||||
self.signatures = signatures
|
||||
self.signatures = signatures or {}
|
||||
self.unrecognized_fields: Mapping[str, Any] = unrecognized_fields or {}
|
||||
|
||||
def __eq__(self, other: Any) -> bool:
|
||||
|
|
@ -480,11 +480,13 @@ def expires(self, value: datetime) -> None:
|
|||
# or "inner metadata")
|
||||
def __init__(
|
||||
self,
|
||||
version: int,
|
||||
spec_version: str,
|
||||
expires: datetime,
|
||||
unrecognized_fields: Optional[Mapping[str, Any]] = None,
|
||||
version: Optional[int],
|
||||
spec_version: Optional[str],
|
||||
expires: Optional[datetime],
|
||||
unrecognized_fields: Optional[Mapping[str, Any]],
|
||||
):
|
||||
if spec_version is None:
|
||||
spec_version = ".".join(SPECIFICATION_VERSION)
|
||||
# Accept semver (X.Y.Z) but also X.Y for legacy compatibility
|
||||
spec_list = spec_version.split(".")
|
||||
if len(spec_list) not in [2, 3] or not all(
|
||||
|
|
@ -497,11 +499,15 @@ def __init__(
|
|||
raise ValueError(f"Unsupported spec_version {spec_version}")
|
||||
|
||||
self.spec_version = spec_version
|
||||
self.expires = expires
|
||||
|
||||
if version <= 0:
|
||||
self.expires = expires or datetime.utcnow() + timedelta(days=1)
|
||||
|
||||
if version is None:
|
||||
version = 1
|
||||
elif version <= 0:
|
||||
raise ValueError(f"version must be > 0, got {version}")
|
||||
self.version = version
|
||||
|
||||
self.unrecognized_fields: Mapping[str, Any] = unrecognized_fields or {}
|
||||
|
||||
def __eq__(self, other: Any) -> bool:
|
||||
|
|
@ -838,20 +844,22 @@ class Root(Signed):
|
|||
# pylint: disable=too-many-arguments
|
||||
def __init__(
|
||||
self,
|
||||
version: int,
|
||||
spec_version: str,
|
||||
expires: datetime,
|
||||
keys: Dict[str, Key],
|
||||
roles: Mapping[str, Role],
|
||||
consistent_snapshot: Optional[bool] = None,
|
||||
version: Optional[int] = None,
|
||||
spec_version: Optional[str] = None,
|
||||
expires: Optional[datetime] = None,
|
||||
keys: Optional[Dict[str, Key]] = None,
|
||||
roles: Optional[Mapping[str, Role]] = None,
|
||||
consistent_snapshot: Optional[bool] = True,
|
||||
unrecognized_fields: Optional[Mapping[str, Any]] = None,
|
||||
):
|
||||
super().__init__(version, spec_version, expires, unrecognized_fields)
|
||||
self.consistent_snapshot = consistent_snapshot
|
||||
self.keys = keys
|
||||
if set(roles) != TOP_LEVEL_ROLE_NAMES:
|
||||
raise ValueError("Role names must be the top-level metadata roles")
|
||||
self.keys = keys or {}
|
||||
|
||||
if roles is None:
|
||||
roles = {r: Role([], 1) for r in TOP_LEVEL_ROLE_NAMES}
|
||||
elif set(roles) != TOP_LEVEL_ROLE_NAMES:
|
||||
raise ValueError("Role names must be the top-level metadata roles")
|
||||
self.roles = roles
|
||||
|
||||
def __eq__(self, other: Any) -> bool:
|
||||
|
|
@ -1129,14 +1137,14 @@ class Timestamp(Signed):
|
|||
|
||||
def __init__(
|
||||
self,
|
||||
version: int,
|
||||
spec_version: str,
|
||||
expires: datetime,
|
||||
snapshot_meta: MetaFile,
|
||||
version: Optional[int] = None,
|
||||
spec_version: Optional[str] = None,
|
||||
expires: Optional[datetime] = None,
|
||||
snapshot_meta: Optional[MetaFile] = None,
|
||||
unrecognized_fields: Optional[Mapping[str, Any]] = None,
|
||||
):
|
||||
super().__init__(version, spec_version, expires, unrecognized_fields)
|
||||
self.snapshot_meta = snapshot_meta
|
||||
self.snapshot_meta = snapshot_meta or MetaFile(1)
|
||||
|
||||
def __eq__(self, other: Any) -> bool:
|
||||
if not isinstance(other, Timestamp):
|
||||
|
|
@ -1190,14 +1198,14 @@ class Snapshot(Signed):
|
|||
|
||||
def __init__(
|
||||
self,
|
||||
version: int,
|
||||
spec_version: str,
|
||||
expires: datetime,
|
||||
meta: Dict[str, MetaFile],
|
||||
version: Optional[int] = None,
|
||||
spec_version: Optional[str] = None,
|
||||
expires: Optional[datetime] = None,
|
||||
meta: Optional[Dict[str, MetaFile]] = None,
|
||||
unrecognized_fields: Optional[Mapping[str, Any]] = None,
|
||||
):
|
||||
super().__init__(version, spec_version, expires, unrecognized_fields)
|
||||
self.meta = meta
|
||||
self.meta = meta if meta is not None else {"targets.json": MetaFile(1)}
|
||||
|
||||
def __eq__(self, other: Any) -> bool:
|
||||
if not isinstance(other, Snapshot):
|
||||
|
|
@ -1660,15 +1668,15 @@ class Targets(Signed):
|
|||
# pylint: disable=too-many-arguments
|
||||
def __init__(
|
||||
self,
|
||||
version: int,
|
||||
spec_version: str,
|
||||
expires: datetime,
|
||||
targets: Dict[str, TargetFile],
|
||||
version: Optional[int] = None,
|
||||
spec_version: Optional[str] = None,
|
||||
expires: Optional[datetime] = None,
|
||||
targets: Optional[Dict[str, TargetFile]] = None,
|
||||
delegations: Optional[Delegations] = None,
|
||||
unrecognized_fields: Optional[Mapping[str, Any]] = None,
|
||||
) -> None:
|
||||
super().__init__(version, spec_version, expires, unrecognized_fields)
|
||||
self.targets = targets
|
||||
self.targets = targets or {}
|
||||
self.delegations = delegations
|
||||
|
||||
def __eq__(self, other: Any) -> bool:
|
||||
|
|
|
|||
Loading…
Reference in a new issue