6060
6161import logging
6262import os
63- from typing import Any , Dict , List , Optional , Set , Tuple
63+ from typing import List , Optional , Set , Tuple
6464from urllib import parse
6565
6666from securesystemslib import util as sslib_util
6767
6868from tuf import exceptions
69- from tuf .api .metadata import Targets
69+ from tuf .api .metadata import TargetFile , Targets
7070from tuf .ngclient ._internal import requests_fetcher , trusted_metadata_set
7171from tuf .ngclient .config import UpdaterConfig
7272from tuf .ngclient .fetcher import FetcherInterface
@@ -144,8 +144,8 @@ def refresh(self) -> None:
144144
145145 def get_one_valid_targetinfo (
146146 self , target_path : str
147- ) -> Optional [Dict [ str , Any ] ]:
148- """Returns target information for 'target_path'.
147+ ) -> Optional [TargetFile ]:
148+ """Returns TargetFile instance with information for 'target_path'.
149149
150150 The return value can be used as an argument to
151151 :func:`download_target()` and :func:`updated_targets()`.
@@ -172,14 +172,14 @@ def get_one_valid_targetinfo(
172172 TODO: download-related errors
173173
174174 Returns:
175- A targetinfo dictionary or None
175+ A TargetFile instance or None.
176176 """
177177 return self ._preorder_depth_first_walk (target_path )
178178
179179 @staticmethod
180180 def updated_targets (
181- targets : List [Dict [ str , Any ] ], destination_directory : str
182- ) -> List [Dict [ str , Any ] ]:
181+ targets : List [TargetFile ], destination_directory : str
182+ ) -> List [TargetFile ]:
183183 """Checks whether local cached target files are up to date
184184
185185 After retrieving the target information for the targets that should be
@@ -202,17 +202,14 @@ def updated_targets(
202202 # against each hash listed for its fileinfo. Note: join() discards
203203 # 'destination_directory' if 'filepath' contains a leading path
204204 # separator (i.e., is treated as an absolute path).
205- filepath = target ["filepath" ]
206- target_fileinfo : "TargetFile" = target ["fileinfo" ]
207-
208- target_filepath = os .path .join (destination_directory , filepath )
205+ target_filepath = os .path .join (destination_directory , target .path )
209206
210207 if target_filepath in updated_targetpaths :
211208 continue
212209
213210 try :
214211 with open (target_filepath , "rb" ) as target_file :
215- target_fileinfo .verify_length_and_hashes (target_file )
212+ target .verify_length_and_hashes (target_file )
216213 # If the file does not exist locally or length and hashes
217214 # do not match, append to updated targets.
218215 except (OSError , exceptions .LengthOrHashMismatchError ):
@@ -223,15 +220,15 @@ def updated_targets(
223220
224221 def download_target (
225222 self ,
226- targetinfo : Dict ,
223+ targetinfo : TargetFile ,
227224 destination_directory : str ,
228225 target_base_url : Optional [str ] = None ,
229226 ):
230227 """Downloads the target file specified by 'targetinfo'.
231228
232229 Args:
233- targetinfo: data received from get_one_valid_targetinfo() or
234- updated_targets().
230+ targetinfo: TargetFile instance received from
231+ get_one_valid_targetinfo() or updated_targets().
235232 destination_directory: existing local directory to download into.
236233 Note that new directories may be created inside
237234 destination_directory as required.
@@ -252,27 +249,26 @@ def download_target(
252249 else :
253250 target_base_url = _ensure_trailing_slash (target_base_url )
254251
255- target_fileinfo : "TargetFile" = targetinfo ["fileinfo" ]
256- target_filepath = targetinfo ["filepath" ]
252+ target_filepath = targetinfo .path
257253 consistent_snapshot = self ._trusted_set .root .signed .consistent_snapshot
258254 if consistent_snapshot and self .config .prefix_targets_with_hash :
259- hashes = list (target_fileinfo .hashes .values ())
255+ hashes = list (targetinfo .hashes .values ())
260256 target_filepath = f"{ hashes [0 ]} .{ target_filepath } "
261257 full_url = parse .urljoin (target_base_url , target_filepath )
262258
263259 with self ._fetcher .download_file (
264- full_url , target_fileinfo .length
260+ full_url , targetinfo .length
265261 ) as target_file :
266262 try :
267- target_fileinfo .verify_length_and_hashes (target_file )
263+ targetinfo .verify_length_and_hashes (target_file )
268264 except exceptions .LengthOrHashMismatchError as e :
269265 raise exceptions .RepositoryError (
270266 f"{ target_filepath } length or hashes do not match"
271267 ) from e
272268
273269 # Store the target file name without the HASH prefix.
274270 local_filepath = os .path .join (
275- destination_directory , targetinfo [ "filepath" ]
271+ destination_directory , targetinfo . path
276272 )
277273 sslib_util .persist_temp_file (target_file , local_filepath )
278274
@@ -381,7 +377,7 @@ def _load_targets(self, role: str, parent_role: str) -> None:
381377
382378 def _preorder_depth_first_walk (
383379 self , target_filepath : str
384- ) -> Optional [Dict [ str , Any ] ]:
380+ ) -> Optional [TargetFile ]:
385381 """
386382 Interrogates the tree of target delegations in order of appearance
387383 (which implicitly order trustworthiness), and returns the matching
@@ -414,7 +410,7 @@ def _preorder_depth_first_walk(
414410
415411 if target is not None :
416412 logger .debug ("Found target in current role %s" , role_name )
417- return { "filepath" : target_filepath , "fileinfo" : target }
413+ return target
418414
419415 # After preorder check, add current role to set of visited roles.
420416 visited_role_names .add ((role_name , parent_role ))
0 commit comments