Skip to content

Commit ec8d45c

Browse files
authored
Use __future__.annotations module (#914)
* Use __future.annotations module This allows us to use even python 3.10 annotation features already. * start using "X | None" instead of Optional[X] * Drop the quotes from factory function return values This also keeps us compatible with python 3.8 for now. Signed-off-by: Jussi Kukkonen <[email protected]> * pyproject: Don't require Python 3.9 quite yet We are still compatible with 3.8: let's not be the first ones to drop compatibility. Signed-off-by: Jussi Kukkonen <[email protected]> --------- Signed-off-by: Jussi Kukkonen <[email protected]>
1 parent d84c1fc commit ec8d45c

16 files changed

+100
-78
lines changed

pyproject.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ classifiers = [
3838
"Topic :: Security",
3939
"Topic :: Software Development",
4040
]
41-
requires-python = "~=3.9"
41+
requires-python = "~=3.8"
4242
dynamic = ["version"]
4343

4444
[project.urls]

securesystemslib/_gpg/constants.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,21 @@
1616
handling
1717
"""
1818

19+
from __future__ import annotations
20+
1921
import functools
2022
import logging
2123
import os
2224
import shlex
2325
import subprocess
24-
from typing import Optional
2526

2627
log = logging.getLogger(__name__)
2728

2829
GPG_TIMEOUT = 10
2930

3031

3132
@functools.lru_cache(maxsize=3)
32-
def is_available_gnupg(gnupg: str, timeout: Optional[int] = None) -> bool:
33+
def is_available_gnupg(gnupg: str, timeout: int | None = None) -> bool:
3334
"""Returns whether gnupg points to a gpg binary."""
3435
if timeout is None:
3536
timeout = GPG_TIMEOUT

securesystemslib/dsse.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
"""Dead Simple Signing Envelope"""
22

3+
from __future__ import annotations
4+
35
import logging
46
from typing import Any
57

@@ -41,7 +43,7 @@ def __eq__(self, other: Any) -> bool:
4143
)
4244

4345
@classmethod
44-
def from_dict(cls, data: dict) -> "Envelope":
46+
def from_dict(cls, data: dict) -> Envelope:
4547
"""Creates a DSSE Envelope from its JSON/dict representation.
4648
4749
Arguments:

securesystemslib/signer/_aws_signer.py

+6-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
"""Signer implementation for AWS Key Management Service"""
22

3+
from __future__ import annotations
4+
35
import logging
4-
from typing import Optional
56
from urllib import parse
67

78
from securesystemslib.exceptions import (
@@ -91,8 +92,8 @@ def from_priv_key_uri(
9192
cls,
9293
priv_key_uri: str,
9394
public_key: Key,
94-
secrets_handler: Optional[SecretsHandler] = None,
95-
) -> "AWSSigner":
95+
secrets_handler: SecretsHandler | None = None,
96+
) -> AWSSigner:
9697
uri = parse.urlparse(priv_key_uri)
9798

9899
if uri.scheme != cls.SCHEME:
@@ -101,7 +102,7 @@ def from_priv_key_uri(
101102
return cls(uri.path, public_key)
102103

103104
@classmethod
104-
def _get_default_scheme(cls, supported_by_key: list[str]) -> Optional[str]:
105+
def _get_default_scheme(cls, supported_by_key: list[str]) -> str | None:
105106
# Iterate over supported AWS algorithms, pick the **first** that is also
106107
# supported by the key, and return the related securesystemslib scheme.
107108
for scheme, algo in cls.aws_algos.items():
@@ -119,7 +120,7 @@ def _get_keytype_for_scheme(scheme: str) -> str:
119120

120121
@classmethod
121122
def import_(
122-
cls, aws_key_id: str, local_scheme: Optional[str] = None
123+
cls, aws_key_id: str, local_scheme: str | None = None
123124
) -> tuple[str, Key]:
124125
"""Loads a key and signer details from AWS KMS.
125126

securesystemslib/signer/_azure_signer.py

+11-10
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
"""Signer implementation for Azure Key Vault"""
22

3+
from __future__ import annotations
4+
35
import logging
4-
from typing import Optional
56
from urllib import parse
67

78
import securesystemslib.hash as sslib_hash
@@ -90,10 +91,10 @@ def public_key(self) -> Key:
9091

9192
@staticmethod
9293
def _get_key_vault_key(
93-
cred: "DefaultAzureCredential",
94+
cred: DefaultAzureCredential,
9495
vault_name: str,
9596
key_name: str,
96-
) -> "KeyVaultKey":
97+
) -> KeyVaultKey:
9798
"""Return KeyVaultKey created from the Vault name and key name"""
9899
vault_url = f"https://{vault_name}.vault.azure.net/"
99100

@@ -112,9 +113,9 @@ def _get_key_vault_key(
112113

113114
@staticmethod
114115
def _create_crypto_client(
115-
cred: "DefaultAzureCredential",
116-
kv_key: "KeyVaultKey",
117-
) -> "CryptographyClient":
116+
cred: DefaultAzureCredential,
117+
kv_key: KeyVaultKey,
118+
) -> CryptographyClient:
118119
"""Return CryptographyClient created Azure credentials and a KeyVaultKey"""
119120
try:
120121
return CryptographyClient(kv_key, credential=cred)
@@ -128,7 +129,7 @@ def _create_crypto_client(
128129
raise e
129130

130131
@staticmethod
131-
def _get_signature_algorithm(public_key: Key) -> "SignatureAlgorithm":
132+
def _get_signature_algorithm(public_key: Key) -> SignatureAlgorithm:
132133
"""Return SignatureAlgorithm after parsing the public key"""
133134
if public_key.keytype != "ecdsa":
134135
logger.info("only EC keys are supported for now")
@@ -148,7 +149,7 @@ def _get_signature_algorithm(public_key: Key) -> "SignatureAlgorithm":
148149
raise UnsupportedKeyType("Unsupported curve supplied by key")
149150

150151
@staticmethod
151-
def _get_hash_algorithm(public_key: "Key") -> str:
152+
def _get_hash_algorithm(public_key: Key) -> str:
152153
"""Return the hash algorithm used by the public key"""
153154
# Format is "ecdsa-sha2-nistp256"
154155
comps = public_key.scheme.split("-")
@@ -180,8 +181,8 @@ def from_priv_key_uri(
180181
cls,
181182
priv_key_uri: str,
182183
public_key: Key,
183-
secrets_handler: Optional[SecretsHandler] = None,
184-
) -> "AzureSigner":
184+
secrets_handler: SecretsHandler | None = None,
185+
) -> AzureSigner:
185186
uri = parse.urlparse(priv_key_uri)
186187

187188
if uri.scheme != cls.SCHEME:

securesystemslib/signer/_gcp_signer.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
"""Signer implementation for Google Cloud KMS"""
22

3+
from __future__ import annotations
4+
35
import logging
4-
from typing import Optional
56
from urllib import parse
67

78
import securesystemslib.hash as sslib_hash
@@ -73,8 +74,8 @@ def from_priv_key_uri(
7374
cls,
7475
priv_key_uri: str,
7576
public_key: Key,
76-
secrets_handler: Optional[SecretsHandler] = None,
77-
) -> "GCPSigner":
77+
secrets_handler: SecretsHandler | None = None,
78+
) -> GCPSigner:
7879
uri = parse.urlparse(priv_key_uri)
7980

8081
if uri.scheme != cls.SCHEME:

securesystemslib/signer/_gpg_signer.py

+8-6
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
"""Signer implementation for OpenPGP"""
22

3+
from __future__ import annotations
4+
35
import logging
4-
from typing import Any, Optional
6+
from typing import Any
57
from urllib import parse
68

79
from securesystemslib import exceptions
@@ -32,7 +34,7 @@ class GPGKey(Key):
3234
"""
3335

3436
@classmethod
35-
def from_dict(cls, keyid: str, key_dict: dict[str, Any]) -> "GPGKey":
37+
def from_dict(cls, keyid: str, key_dict: dict[str, Any]) -> GPGKey:
3638
keytype, scheme, keyval = cls._from_dict(key_dict)
3739
return cls(keyid, keytype, scheme, keyval, key_dict)
3840

@@ -84,7 +86,7 @@ class GPGSigner(Signer):
8486
def __init__(
8587
self,
8688
public_key: Key,
87-
homedir: Optional[str] = None,
89+
homedir: str | None = None,
8890
):
8991
self.homedir = homedir
9092
self._public_key = public_key
@@ -98,8 +100,8 @@ def from_priv_key_uri(
98100
cls,
99101
priv_key_uri: str,
100102
public_key: Key,
101-
secrets_handler: Optional[SecretsHandler] = None,
102-
) -> "GPGSigner":
103+
secrets_handler: SecretsHandler | None = None,
104+
) -> GPGSigner:
103105
if not isinstance(public_key, GPGKey):
104106
raise ValueError(f"expected GPGKey for {priv_key_uri}")
105107

@@ -147,7 +149,7 @@ def _key_from_legacy_dict(key_dict: dict[str, Any]) -> GPGKey:
147149
return GPGKey(keyid, keytype, scheme, keyval)
148150

149151
@classmethod
150-
def import_(cls, keyid: str, homedir: Optional[str] = None) -> tuple[str, Key]:
152+
def import_(cls, keyid: str, homedir: str | None = None) -> tuple[str, Key]:
151153
"""Load key and signer details from GnuPG keyring.
152154
153155
NOTE: Information about the key validity (expiration, revocation, etc.)

securesystemslib/signer/_hsm_signer.py

+11-10
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@
55
66
"""
77

8+
from __future__ import annotations
9+
810
import binascii
911
from collections.abc import Iterator
1012
from contextlib import contextmanager
11-
from typing import Optional
1213
from urllib import parse
1314

1415
from securesystemslib.exceptions import UnsupportedLibraryError
@@ -184,7 +185,7 @@ def _find_pkcs_slot(filters: dict[str, str]) -> int:
184185

185186
@staticmethod
186187
@contextmanager
187-
def _get_session(filters: dict[str, str]) -> Iterator["PyKCS11.Session"]:
188+
def _get_session(filters: dict[str, str]) -> Iterator[PyKCS11.Session]:
188189
"""Context manager to handle a HSM session.
189190
190191
The cryptographic token is selected by filtering by token info fields.
@@ -201,9 +202,9 @@ def _get_session(filters: dict[str, str]) -> Iterator["PyKCS11.Session"]:
201202
@classmethod
202203
def _find_key(
203204
cls,
204-
session: "PyKCS11.Session",
205+
session: PyKCS11.Session,
205206
keyid: int,
206-
key_type: Optional[int] = None,
207+
key_type: int | None = None,
207208
) -> int:
208209
"""Find ecdsa key on HSM."""
209210
if key_type is None:
@@ -226,8 +227,8 @@ def _find_key(
226227

227228
@classmethod
228229
def _find_key_values(
229-
cls, session: "PyKCS11.Session", keyid: int
230-
) -> tuple["ECDomainParameters", bytes]:
230+
cls, session: PyKCS11.Session, keyid: int
231+
) -> tuple[ECDomainParameters, bytes]:
231232
"""Find ecdsa public key values on HSM."""
232233
key = cls._find_key(session, keyid)
233234
params, point = session.getAttributeValue(
@@ -261,8 +262,8 @@ def _build_token_filter(cls) -> dict[str, str]:
261262
@classmethod
262263
def import_(
263264
cls,
264-
hsm_keyid: Optional[int] = None,
265-
token_filter: Optional[dict[str, str]] = None,
265+
hsm_keyid: int | None = None,
266+
token_filter: dict[str, str] | None = None,
266267
) -> tuple[str, SSlibKey]:
267268
"""Import public key and signer details from HSM.
268269
@@ -337,8 +338,8 @@ def from_priv_key_uri(
337338
cls,
338339
priv_key_uri: str,
339340
public_key: Key,
340-
secrets_handler: Optional[SecretsHandler] = None,
341-
) -> "HSMSigner":
341+
secrets_handler: SecretsHandler | None = None,
342+
) -> HSMSigner:
342343
if not isinstance(public_key, SSlibKey):
343344
raise ValueError(f"expected SSlibKey for {priv_key_uri}")
344345

securesystemslib/signer/_key.py

+15-15
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
"""Key interface and the default implementations"""
22

3+
from __future__ import annotations
4+
35
import logging
46
from abc import ABCMeta, abstractmethod
5-
from typing import Any, Optional, cast
7+
from typing import Any, cast
68

79
from securesystemslib._vendor.ed25519.ed25519 import (
810
SignatureMismatch,
@@ -94,7 +96,7 @@ def __init__(
9496
keytype: str,
9597
scheme: str,
9698
keyval: dict[str, Any],
97-
unrecognized_fields: Optional[dict[str, Any]] = None,
99+
unrecognized_fields: dict[str, Any] | None = None,
98100
):
99101
if not all(
100102
isinstance(at, str) for at in [keyid, keytype, scheme]
@@ -124,7 +126,7 @@ def __eq__(self, other: Any) -> bool:
124126

125127
@classmethod
126128
@abstractmethod
127-
def from_dict(cls, keyid: str, key_dict: dict[str, Any]) -> "Key":
129+
def from_dict(cls, keyid: str, key_dict: dict[str, Any]) -> Key:
128130
"""Creates ``Key`` object from a serialization dict
129131
130132
Key implementations must override this factory constructor that is used
@@ -207,14 +209,14 @@ def __init__(
207209
keytype: str,
208210
scheme: str,
209211
keyval: dict[str, Any],
210-
unrecognized_fields: Optional[dict[str, Any]] = None,
212+
unrecognized_fields: dict[str, Any] | None = None,
211213
):
212214
if "public" not in keyval or not isinstance(keyval["public"], str):
213215
raise ValueError(f"public key string required for scheme {scheme}")
214216
super().__init__(keyid, keytype, scheme, keyval, unrecognized_fields)
215217

216218
@classmethod
217-
def from_dict(cls, keyid: str, key_dict: dict[str, Any]) -> "SSlibKey":
219+
def from_dict(cls, keyid: str, key_dict: dict[str, Any]) -> SSlibKey:
218220
keytype, scheme, keyval = cls._from_dict(key_dict)
219221

220222
# All fields left in the key_dict are unrecognized.
@@ -223,13 +225,13 @@ def from_dict(cls, keyid: str, key_dict: dict[str, Any]) -> "SSlibKey":
223225
def to_dict(self) -> dict[str, Any]:
224226
return self._to_dict()
225227

226-
def _crypto_key(self) -> "PublicKeyTypes":
228+
def _crypto_key(self) -> PublicKeyTypes:
227229
"""Helper to get a `cryptography` public key for this SSlibKey."""
228230
public_bytes = self.keyval["public"].encode("utf-8")
229231
return load_pem_public_key(public_bytes)
230232

231233
@staticmethod
232-
def _from_crypto(public_key: "PublicKeyTypes") -> tuple[str, str, str]:
234+
def _from_crypto(public_key: PublicKeyTypes) -> tuple[str, str, str]:
233235
"""Return tuple of keytype, default scheme and serialized public key
234236
value for the passed public key.
235237
@@ -269,10 +271,10 @@ def _pem() -> str:
269271
@classmethod
270272
def from_crypto(
271273
cls,
272-
public_key: "PublicKeyTypes",
273-
keyid: Optional[str] = None,
274-
scheme: Optional[str] = None,
275-
) -> "SSlibKey":
274+
public_key: PublicKeyTypes,
275+
keyid: str | None = None,
276+
scheme: str | None = None,
277+
) -> SSlibKey:
276278
"""Create SSlibKey from pyca/cryptography public key.
277279
278280
Args:
@@ -306,7 +308,7 @@ def from_crypto(
306308
return SSlibKey(keyid, keytype, scheme, keyval)
307309

308310
@staticmethod
309-
def _get_hash_algorithm(name: str) -> "HashAlgorithm":
311+
def _get_hash_algorithm(name: str) -> HashAlgorithm:
310312
"""Helper to return hash algorithm for name."""
311313
algorithm: HashAlgorithm
312314
if name == "sha224":
@@ -321,9 +323,7 @@ def _get_hash_algorithm(name: str) -> "HashAlgorithm":
321323
return algorithm
322324

323325
@staticmethod
324-
def _get_rsa_padding(
325-
name: str, hash_algorithm: "HashAlgorithm"
326-
) -> "AsymmetricPadding":
326+
def _get_rsa_padding(name: str, hash_algorithm: HashAlgorithm) -> AsymmetricPadding:
327327
"""Helper to return rsa signature padding for name."""
328328
padding: AsymmetricPadding
329329
if name == "pss":

0 commit comments

Comments
 (0)