4242 updater.refresh()
4343"""
4444
45+ from __future__ import annotations
46+
4547import datetime
4648import logging
4749import os
4850import tempfile
49- from collections .abc import Iterator
5051from dataclasses import dataclass , field
51- from typing import Optional
52+ from typing import TYPE_CHECKING
5253from urllib import parse
5354
5455import securesystemslib .hash as sslib_hash
7273from tuf .api .serialization .json import JSONSerializer
7374from tuf .ngclient .fetcher import FetcherInterface
7475
76+ if TYPE_CHECKING :
77+ from collections .abc import Iterator
78+
7579logger = logging .getLogger (__name__ )
7680
7781SPEC_VER = "." .join (SPECIFICATION_VERSION )
8185class FetchTracker :
8286 """Fetcher counter for metadata and targets."""
8387
84- metadata : list [tuple [str , Optional [ int ] ]] = field (default_factory = list )
85- targets : list [tuple [str , Optional [ str ] ]] = field (default_factory = list )
88+ metadata : list [tuple [str , int | None ]] = field (default_factory = list )
89+ targets : list [tuple [str , str | None ]] = field (default_factory = list )
8690
8791
8892@dataclass
@@ -116,7 +120,7 @@ def __init__(self) -> None:
116120 # Enable hash-prefixed target file names
117121 self .prefix_targets_with_hash = True
118122
119- self .dump_dir : Optional [ str ] = None
123+ self .dump_dir : str | None = None
120124 self .dump_version = 0
121125
122126 self .fetch_tracker = FetchTracker ()
@@ -201,7 +205,7 @@ def _fetch(self, url: str) -> Iterator[bytes]:
201205 if role == Root .type or (
202206 self .root .consistent_snapshot and ver_and_name != Timestamp .type
203207 ):
204- version : Optional [ int ] = int (version_str )
208+ version : int | None = int (version_str )
205209 else :
206210 # the file is not version-prefixed
207211 role = ver_and_name
@@ -213,7 +217,7 @@ def _fetch(self, url: str) -> Iterator[bytes]:
213217 target_path = path [len ("/targets/" ) :]
214218 dir_parts , sep , prefixed_filename = target_path .rpartition ("/" )
215219 # extract the hash prefix, if any
216- prefix : Optional [ str ] = None
220+ prefix : str | None = None
217221 filename = prefixed_filename
218222 if self .root .consistent_snapshot and self .prefix_targets_with_hash :
219223 prefix , _ , filename = prefixed_filename .partition ("." )
@@ -223,9 +227,7 @@ def _fetch(self, url: str) -> Iterator[bytes]:
223227 else :
224228 raise DownloadHTTPError (f"Unknown path '{ path } '" , 404 )
225229
226- def fetch_target (
227- self , target_path : str , target_hash : Optional [str ]
228- ) -> bytes :
230+ def fetch_target (self , target_path : str , target_hash : str | None ) -> bytes :
229231 """Return data for 'target_path', checking 'target_hash' if it is given.
230232
231233 If hash is None, then consistent_snapshot is not used.
@@ -244,7 +246,7 @@ def fetch_target(
244246 logger .debug ("fetched target %s" , target_path )
245247 return repo_target .data
246248
247- def fetch_metadata (self , role : str , version : Optional [ int ] = None ) -> bytes :
249+ def fetch_metadata (self , role : str , version : int | None = None ) -> bytes :
248250 """Return signed metadata for 'role', using 'version' if it is given.
249251
250252 If version is None, non-versioned metadata is being requested.
@@ -261,7 +263,7 @@ def fetch_metadata(self, role: str, version: Optional[int] = None) -> bytes:
261263 return self .signed_roots [version - 1 ]
262264
263265 # sign and serialize the requested metadata
264- md : Optional [ Metadata ]
266+ md : Metadata | None
265267 if role == Timestamp .type :
266268 md = self .md_timestamp
267269 elif role == Snapshot .type :
0 commit comments