Skip to content

Commit 748f93f

Browse files
committed
Add missing type annotations to updater
Add missing annotations and resolve partially mypy errors in updater.py and trusted_metadata_set.py Signed-off-by: Teodora Sechkova <tsechkova@vmware.com>
1 parent 4b55a62 commit 748f93f

2 files changed

Lines changed: 40 additions & 34 deletions

File tree

tuf/ngclient/_internal/trusted_metadata_set.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,10 @@
6868
import logging
6969
from collections import abc
7070
from datetime import datetime
71-
from typing import Dict, Iterator, Optional
71+
from typing import Dict, Iterator, Mapping, Optional
7272

7373
from tuf import exceptions
74-
from tuf.api.metadata import Metadata, Root, Targets
74+
from tuf.api.metadata import Key, Metadata, Root, Targets
7575
from tuf.api.serialization import DeserializationError
7676

7777
logger = logging.getLogger(__name__)
@@ -83,7 +83,7 @@ def verify_with_threshold(
8383
) -> bool:
8484
"""Verify 'unverified' with keys and threshold defined in delegator"""
8585
role = None
86-
keys = {}
86+
keys: Mapping[str, Key] = {}
8787
if isinstance(delegator.signed, Root):
8888
keys = delegator.signed.keys
8989
role = delegator.signed.roles.get(role_name)
@@ -133,7 +133,7 @@ def __init__(self, root_data: bytes):
133133
RepositoryError: Metadata failed to load or verify. The actual
134134
error type and content will contain more details.
135135
"""
136-
self._trusted_set = {} # type: Dict[str: Metadata]
136+
self._trusted_set = {} # type: Dict[str, Metadata]
137137
self.reference_time = datetime.utcnow()
138138
self._root_update_finished = False
139139

@@ -152,7 +152,7 @@ def __len__(self) -> int:
152152

153153
def __iter__(self) -> Iterator[Metadata]:
154154
"""Returns iterator over all Metadata objects in TrustedMetadataSet"""
155-
return iter(self._trusted_set)
155+
return iter(self._trusted_set.values())
156156

157157
# Helper properties for top level metadata
158158
@property
@@ -176,7 +176,7 @@ def targets(self) -> Optional[Metadata]:
176176
return self._trusted_set.get("targets")
177177

178178
# Methods for updating metadata
179-
def update_root(self, data: bytes):
179+
def update_root(self, data: bytes) -> None:
180180
"""Verifies and loads 'data' as new root metadata.
181181
182182
Note that an expired intermediate root is considered valid: expiry is
@@ -225,7 +225,7 @@ def update_root(self, data: bytes):
225225
self._trusted_set["root"] = new_root
226226
logger.debug("Updated root")
227227

228-
def root_update_finished(self):
228+
def root_update_finished(self) -> None:
229229
"""Marks root metadata as final and verifies it is not expired
230230
231231
Raises:
@@ -245,7 +245,7 @@ def root_update_finished(self):
245245
self._root_update_finished = True
246246
logger.debug("Verified final root.json")
247247

248-
def update_timestamp(self, data: bytes):
248+
def update_timestamp(self, data: bytes) -> None:
249249
"""Verifies and loads 'data' as new timestamp metadata.
250250
251251
Args:
@@ -302,7 +302,7 @@ def update_timestamp(self, data: bytes):
302302
self._trusted_set["timestamp"] = new_timestamp
303303
logger.debug("Updated timestamp")
304304

305-
def update_snapshot(self, data: bytes):
305+
def update_snapshot(self, data: bytes) -> None:
306306
"""Verifies and loads 'data' as new snapshot metadata.
307307
308308
Args:
@@ -379,7 +379,7 @@ def update_snapshot(self, data: bytes):
379379
self._trusted_set["snapshot"] = new_snapshot
380380
logger.debug("Updated snapshot")
381381

382-
def update_targets(self, data: bytes):
382+
def update_targets(self, data: bytes) -> None:
383383
"""Verifies and loads 'data' as new top-level targets metadata.
384384
385385
Args:
@@ -393,7 +393,7 @@ def update_targets(self, data: bytes):
393393

394394
def update_delegated_targets(
395395
self, data: bytes, role_name: str, delegator_name: str
396-
):
396+
) -> None:
397397
"""Verifies and loads 'data' as new metadata for target 'role_name'.
398398
399399
Args:

tuf/ngclient/updater.py

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from securesystemslib import util as sslib_util
1515

1616
from tuf import exceptions
17+
from tuf.api.metadata import DelegatedRole, TargetFile, Targets
1718
from tuf.ngclient._internal import requests_fetcher, trusted_metadata_set
1819
from tuf.ngclient.config import UpdaterConfig
1920
from tuf.ngclient.fetcher import FetcherInterface
@@ -59,12 +60,7 @@ def __init__(
5960
# Read trusted local root metadata
6061
data = self._load_local_metadata("root")
6162
self._trusted_set = trusted_metadata_set.TrustedMetadataSet(data)
62-
63-
if fetcher is None:
64-
self._fetcher = requests_fetcher.RequestsFetcher()
65-
else:
66-
self._fetcher = fetcher
67-
63+
self._fetcher = fetcher or requests_fetcher.RequestsFetcher()
6864
self.config = config or UpdaterConfig()
6965

7066
def refresh(self) -> None:
@@ -91,7 +87,7 @@ def refresh(self) -> None:
9187
self._load_snapshot()
9288
self._load_targets("targets", "root")
9389

94-
def get_one_valid_targetinfo(self, target_path: str) -> Dict:
90+
def get_one_valid_targetinfo(self, target_path: str) -> Dict[str, Any]:
9591
"""
9692
Returns the target information for a target identified by target_path.
9793
@@ -135,7 +131,7 @@ def updated_targets(
135131
# 'destination_directory' if 'filepath' contains a leading path
136132
# separator (i.e., is treated as an absolute path).
137133
filepath = target["filepath"]
138-
target_fileinfo: "TargetFile" = target["fileinfo"]
134+
target_fileinfo: TargetFile = target["fileinfo"]
139135

140136
target_filepath = os.path.join(destination_directory, filepath)
141137

@@ -155,10 +151,10 @@ def updated_targets(
155151

156152
def download_target(
157153
self,
158-
targetinfo: Dict,
154+
targetinfo: Dict[str, Any],
159155
destination_directory: str,
160156
target_base_url: Optional[str] = None,
161-
):
157+
) -> None:
162158
"""
163159
Download target specified by 'targetinfo' into 'destination_directory'.
164160
@@ -175,18 +171,20 @@ def download_target(
175171
TODO: download-related errors
176172
TODO: file write errors
177173
"""
178-
if target_base_url is None and self._target_base_url is None:
179-
raise ValueError(
180-
"target_base_url must be set in either download_target() or "
181-
"constructor"
182-
)
174+
183175
if target_base_url is None:
176+
if self._target_base_url is None:
177+
raise ValueError(
178+
"target_base_url must be set in either "
179+
"download_target() or constructor"
180+
)
181+
184182
target_base_url = self._target_base_url
185183
else:
186184
target_base_url = _ensure_trailing_slash(target_base_url)
187185

188-
target_filepath = targetinfo["filepath"]
189-
target_fileinfo: "TargetFile" = targetinfo["fileinfo"]
186+
target_filepath: str = targetinfo["filepath"]
187+
target_fileinfo: TargetFile = targetinfo["fileinfo"]
190188
full_url = parse.urljoin(target_base_url, target_filepath)
191189

192190
with self._fetcher.download_file(
@@ -217,7 +215,7 @@ def _load_local_metadata(self, rolename: str) -> bytes:
217215
with open(os.path.join(self._dir, f"{rolename}.json"), "rb") as f:
218216
return f.read()
219217

220-
def _persist_metadata(self, rolename: str, data: bytes):
218+
def _persist_metadata(self, rolename: str, data: bytes) -> None:
221219
with open(os.path.join(self._dir, f"{rolename}.json"), "wb") as f:
222220
f.write(data)
223221

@@ -275,6 +273,7 @@ def _load_snapshot(self) -> None:
275273
# Local snapshot does not exist or is invalid: update from remote
276274
logger.debug("Failed to load local snapshot %s", e)
277275

276+
assert self._trusted_set.timestamp is not None
278277
metainfo = self._trusted_set.timestamp.signed.meta["snapshot.json"]
279278
length = metainfo.length or self.config.snapshot_max_length
280279
version = None
@@ -295,6 +294,7 @@ def _load_targets(self, role: str, parent_role: str) -> None:
295294
# Local 'role' does not exist or is invalid: update from remote
296295
logger.debug("Failed to load local %s: %s", role, e)
297296

297+
assert self._trusted_set.snapshot is not None
298298
metainfo = self._trusted_set.snapshot.signed.meta[f"{role}.json"]
299299
length = metainfo.length or self.config.targets_max_length
300300
version = None
@@ -305,7 +305,9 @@ def _load_targets(self, role: str, parent_role: str) -> None:
305305
self._trusted_set.update_delegated_targets(data, role, parent_role)
306306
self._persist_metadata(role, data)
307307

308-
def _preorder_depth_first_walk(self, target_filepath) -> Dict:
308+
def _preorder_depth_first_walk(
309+
self, target_filepath: str
310+
) -> Dict[str, Any]:
309311
"""
310312
Interrogates the tree of target delegations in order of appearance
311313
(which implicitly order trustworthiness), and returns the matching
@@ -333,7 +335,7 @@ def _preorder_depth_first_walk(self, target_filepath) -> Dict:
333335
# The metadata for 'role_name' must be downloaded/updated before
334336
# its targets, delegations, and child roles can be inspected.
335337

336-
role_metadata = self._trusted_set[role_name].signed
338+
role_metadata: Targets = self._trusted_set[role_name].signed
337339
target = role_metadata.targets.get(target_filepath)
338340

339341
# After preorder check, add current role to set of visited roles.
@@ -400,7 +402,9 @@ def _preorder_depth_first_walk(self, target_filepath) -> Dict:
400402
return {"filepath": target_filepath, "fileinfo": target}
401403

402404

403-
def _visit_child_role(child_role: Dict, target_filepath: str) -> str:
405+
def _visit_child_role(
406+
child_role: DelegatedRole, target_filepath: str
407+
) -> Optional[str]:
404408
"""
405409
<Purpose>
406410
Non-public method that determines whether the given 'target_filepath'
@@ -496,7 +500,9 @@ def _visit_child_role(child_role: Dict, target_filepath: str) -> str:
496500
return None
497501

498502

499-
def _get_filepath_hash(target_filepath, hash_function="sha256"):
503+
def _get_filepath_hash(
504+
target_filepath: str, hash_function: str = "sha256"
505+
) -> str:
500506
"""
501507
Calculate the hash of the filepath to determine which bin to find the
502508
target.
@@ -511,6 +517,6 @@ def _get_filepath_hash(target_filepath, hash_function="sha256"):
511517
return target_filepath_hash
512518

513519

514-
def _ensure_trailing_slash(url: str):
520+
def _ensure_trailing_slash(url: str) -> str:
515521
"""Return url guaranteed to end in a slash"""
516522
return url if url.endswith("/") else f"{url}/"

0 commit comments

Comments
 (0)