From 628e6facd192d52ab8ac101c8fe9bb4aaa30c473 Mon Sep 17 00:00:00 2001 From: Kai Mueller Date: Mon, 23 Sep 2024 11:27:26 +0000 Subject: [PATCH 1/5] Add basic jwcrypto stubs --- pyrightconfig.stricter.json | 3 +- stubs/jwcrypto/METADATA.toml | 2 + stubs/jwcrypto/jwcrypto/__init__.pyi | 0 stubs/jwcrypto/jwcrypto/common.pyi | 48 ++++++++++ stubs/jwcrypto/jwcrypto/jwa.pyi | 35 ++++++++ stubs/jwcrypto/jwcrypto/jwe.pyi | 51 +++++++++++ stubs/jwcrypto/jwcrypto/jwk.pyi | 125 +++++++++++++++++++++++++++ stubs/jwcrypto/jwcrypto/jws.pyi | 52 +++++++++++ stubs/jwcrypto/jwcrypto/jwt.pyi | 76 ++++++++++++++++ 9 files changed, 391 insertions(+), 1 deletion(-) create mode 100644 stubs/jwcrypto/METADATA.toml create mode 100644 stubs/jwcrypto/jwcrypto/__init__.pyi create mode 100644 stubs/jwcrypto/jwcrypto/common.pyi create mode 100644 stubs/jwcrypto/jwcrypto/jwa.pyi create mode 100644 stubs/jwcrypto/jwcrypto/jwe.pyi create mode 100644 stubs/jwcrypto/jwcrypto/jwk.pyi create mode 100644 stubs/jwcrypto/jwcrypto/jws.pyi create mode 100644 stubs/jwcrypto/jwcrypto/jwt.pyi diff --git a/pyrightconfig.stricter.json b/pyrightconfig.stricter.json index a3ea8b6478dc..c9f6557a132e 100644 --- a/pyrightconfig.stricter.json +++ b/pyrightconfig.stricter.json @@ -57,6 +57,7 @@ "stubs/influxdb-client", "stubs/jmespath", "stubs/jsonschema", + "stubs/jwcrypto", "stubs/ldap3", "stubs/Markdown", "stubs/mysqlclient", @@ -100,7 +101,7 @@ "stubs/vobject", "stubs/workalendar", "stubs/wurlitzer", - "stubs/xdgenvpy" + "stubs/xdgenvpy", ], "typeCheckingMode": "strict", // TODO: Complete incomplete stubs diff --git a/stubs/jwcrypto/METADATA.toml b/stubs/jwcrypto/METADATA.toml new file mode 100644 index 000000000000..9945697aaa2a --- /dev/null +++ b/stubs/jwcrypto/METADATA.toml @@ -0,0 +1,2 @@ +version = "1.5.*" +upstream_repository = "https://github.com/latchset/jwcrypto" diff --git a/stubs/jwcrypto/jwcrypto/__init__.pyi b/stubs/jwcrypto/jwcrypto/__init__.pyi new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/stubs/jwcrypto/jwcrypto/common.pyi b/stubs/jwcrypto/jwcrypto/common.pyi new file mode 100644 index 000000000000..10ee692c3fa2 --- /dev/null +++ b/stubs/jwcrypto/jwcrypto/common.pyi @@ -0,0 +1,48 @@ +from _typeshed import Incomplete +from collections.abc import Iterator, MutableMapping +from typing import Any, NamedTuple + +def base64url_encode(payload: str | bytes) -> str: ... +def base64url_decode(payload: str) -> bytes: ... +def json_encode(string: str | bytes) -> str: ... + +# The function returns json.loads which returns Any +def json_decode(string: str | bytes) -> Any: ... + +class JWException(Exception): ... + +class InvalidJWAAlgorithm(JWException): + def __init__(self, message: str | None = None) -> None: ... + +class InvalidCEKeyLength(JWException): + def __init__(self, expected: int, obtained: int) -> None: ... + +class InvalidJWEOperation(JWException): + def __init__(self, message: str | None = None, exception: BaseException | None = None) -> None: ... + +class InvalidJWEKeyType(JWException): + def __init__(self, expected: int, obtained: int) -> None: ... + +class InvalidJWEKeyLength(JWException): + def __init__(self, expected: int, obtained: int) -> None: ... + +class InvalidJWSERegOperation(JWException): + def __init__(self, message: str | None = None, exception: BaseException | None = None) -> None: ... + +class JWKeyNotFound(JWException): + def __init__(self, message: str | None = None) -> None: ... + +class JWSEHeaderParameter(NamedTuple): + description: str + mustprotect: bool + supported: bool + check_fn: Incomplete | None + +class JWSEHeaderRegistry(MutableMapping[str, JWSEHeaderParameter]): + def __init__(self, init_registry: Incomplete | None = None) -> None: ... + def check_header(self, h: str, value) -> bool: ... + def __getitem__(self, key: str) -> JWSEHeaderParameter: ... + def __iter__(self) -> Iterator[str]: ... + def __delitem__(self, key: str) -> None: ... + def __setitem__(self, h: str, jwse_header_param: JWSEHeaderParameter) -> None: ... + def __len__(self) -> int: ... diff --git a/stubs/jwcrypto/jwcrypto/jwa.pyi b/stubs/jwcrypto/jwcrypto/jwa.pyi new file mode 100644 index 000000000000..dc6aff867f17 --- /dev/null +++ b/stubs/jwcrypto/jwcrypto/jwa.pyi @@ -0,0 +1,35 @@ +from abc import ABCMeta, abstractmethod +from collections.abc import Mapping +from typing import ClassVar + +default_max_pbkdf2_iterations: int + +class JWAAlgorithm(metaclass=ABCMeta): + @property + @abstractmethod + def name(self) -> str: ... + @property + @abstractmethod + def description(self) -> str: ... + @property + @abstractmethod + def keysize(self) -> int: ... + @property + @abstractmethod + def algorithm_usage_location(self) -> str: ... + @property + @abstractmethod + def algorithm_use(self) -> str: ... + @property + def input_keysize(self) -> int: ... + +class JWA: + algorithms_registry: ClassVar[Mapping[str, JWAAlgorithm]] + @classmethod + def instantiate_alg(cls, name: str, use: str | None = None) -> JWAAlgorithm: ... + @classmethod + def signing_alg(cls, name: str) -> JWAAlgorithm: ... + @classmethod + def keymgmt_alg(cls, name: str) -> JWAAlgorithm: ... + @classmethod + def encryption_alg(cls, name: str) -> JWAAlgorithm: ... diff --git a/stubs/jwcrypto/jwcrypto/jwe.pyi b/stubs/jwcrypto/jwcrypto/jwe.pyi new file mode 100644 index 000000000000..408b8850d522 --- /dev/null +++ b/stubs/jwcrypto/jwcrypto/jwe.pyi @@ -0,0 +1,51 @@ +from _typeshed import Incomplete +from collections.abc import Mapping, Sequence + +from jwcrypto import common +from jwcrypto.common import JWException, JWSEHeaderParameter +from jwcrypto.jwk import JWK, JWKSet + +default_max_compressed_size: int +JWEHeaderRegistry: Mapping[str, JWSEHeaderParameter] +default_allowed_algs: Sequence[str] + +class InvalidJWEData(JWException): + def __init__(self, message: str | None = None, exception: BaseException | None = None) -> None: ... + +InvalidCEKeyLength = common.InvalidCEKeyLength +InvalidJWEKeyLength = common.InvalidJWEKeyLength +InvalidJWEKeyType = common.InvalidJWEKeyType +InvalidJWEOperation = common.InvalidJWEOperation + +class JWE: + objects: Incomplete + plaintext: Incomplete + header_registry: Incomplete + cek: Incomplete + decryptlog: Incomplete + def __init__( + self, + plaintext: bytes | None = None, + protected: str | None = None, + unprotected: str | None = None, + aad: bytes | None = None, + algs: Incomplete | None = None, + recipient: str | None = None, + header: Incomplete | None = None, + header_registry: Incomplete | None = None, + ) -> None: ... + @property + def allowed_algs(self): ... + @allowed_algs.setter + def allowed_algs(self, algs) -> None: ... + def add_recipient(self, key, header: Incomplete | None = None) -> None: ... + def serialize(self, compact: bool = False): ... + def decrypt(self, key: JWK | JWKSet) -> None: ... + def deserialize(self, raw_jwe: str | bytes, key: JWK | JWKSet | None = None) -> None: ... + @property + def payload(self): ... + @property + def jose_header(self) -> dict[Incomplete, Incomplete]: ... + @classmethod + def from_jose_token(cls, token: str | bytes) -> JWE: ... + def __eq__(self, other: object) -> bool: ... diff --git a/stubs/jwcrypto/jwcrypto/jwk.pyi b/stubs/jwcrypto/jwcrypto/jwk.pyi new file mode 100644 index 000000000000..94fdc4b37952 --- /dev/null +++ b/stubs/jwcrypto/jwcrypto/jwk.pyi @@ -0,0 +1,125 @@ +from _typeshed import Incomplete +from collections.abc import Iterator, Sequence +from enum import Enum +from typing import Any, NamedTuple + +from jwcrypto.common import JWException + +class UnimplementedOKPCurveKey: + @classmethod + def generate(cls) -> None: ... + @classmethod + def from_public_bytes(cls, *args) -> None: ... + @classmethod + def from_private_bytes(cls, *args) -> None: ... + +ImplementedOkpCurves: Sequence[str] +Ed25519PublicKey = UnimplementedOKPCurveKey +Ed25519PrivateKey = UnimplementedOKPCurveKey +Ed448PublicKey = UnimplementedOKPCurveKey +Ed448PrivateKey = UnimplementedOKPCurveKey +priv_bytes: Incomplete +X25519PublicKey = UnimplementedOKPCurveKey +X25519PrivateKey = UnimplementedOKPCurveKey +X448PublicKey = UnimplementedOKPCurveKey +X448PrivateKey = UnimplementedOKPCurveKey + +JWKTypesRegistry: Incomplete + +class ParmType(Enum): + name: str + b64: str + b64u: str + unsupported: str + +class JWKParameter(NamedTuple): + description: Incomplete + public: Incomplete + required: Incomplete + type: Incomplete + +JWKValuesRegistry: Incomplete +JWKParamsRegistry: Incomplete +JWKEllipticCurveRegistry: Incomplete +JWKUseRegistry: Incomplete +JWKOperationsRegistry: Incomplete +JWKpycaCurveMap: Incomplete +IANANamedInformationHashAlgorithmRegistry: Incomplete + +class InvalidJWKType(JWException): + value: Incomplete + def __init__(self, value: Incomplete | None = None) -> None: ... + +class InvalidJWKUsage(JWException): + value: Incomplete + use: Incomplete + def __init__(self, use, value) -> None: ... + +class InvalidJWKOperation(JWException): + op: Incomplete + values: Incomplete + def __init__(self, operation, values) -> None: ... + +class InvalidJWKValue(JWException): ... + +class JWK(dict[str, Any]): + def __init__(self, **kwargs) -> None: ... + @classmethod + def generate(cls, **kwargs): ... + def generate_key(self, **params) -> None: ... + def import_key(self, **kwargs) -> None: ... + @classmethod + def from_json(cls, key): ... + def export(self, private_key: bool = True, as_dict: bool = False): ... + def export_public(self, as_dict: bool = False): ... + def export_private(self, as_dict: bool = False): ... + def export_symmetric(self, as_dict: bool = False): ... + def public(self): ... + @property + def has_public(self) -> bool: ... + @property + def has_private(self) -> bool: ... + @property + def is_symmetric(self) -> bool: ... + @property + def key_type(self): ... + @property + def key_id(self): ... + @property + def key_curve(self): ... + def get_curve(self, arg): ... + def get_op_key(self, operation: Incomplete | None = None, arg: Incomplete | None = None): ... + def import_from_pyca(self, key) -> None: ... + def import_from_pem(self, data, password: Incomplete | None = None, kid: Incomplete | None = None) -> None: ... + def export_to_pem(self, private_key: bool = False, password: bool = False): ... + @classmethod + def from_pyca(cls, key): ... + @classmethod + def from_pem(cls, data, password: Incomplete | None = None): ... + def thumbprint(self, hashalg=...): ... + def thumbprint_uri(self, hname: str = "sha-256"): ... + def __setitem__(self, item, value) -> None: ... + def update(self, *args, **kwargs) -> None: ... + def setdefault(self, key, default: Incomplete | None = None): ... + def __delitem__(self, item) -> None: ... + def __eq__(self, other: object) -> bool: ... + def __hash__(self): ... + def __getattr__(self, item: str): ... + def __setattr__(self, item: str, value) -> None: ... + @classmethod + def from_password(cls, password): ... + +class JWKSet(dict[str, Any]): + def __init__(self, *args: Any, **kwargs: Any) -> None: ... + def __iter__(self) -> Iterator[Any]: ... + def __contains__(self, key) -> bool: ... + def __setitem__(self, key: str, val: Any) -> None: ... + def update(self, *args, **kwargs) -> None: ... + def setdefault(self, key: str, default: Incomplete | None = None): ... + def add(self, elem) -> None: ... + def export(self, private_keys: bool = True, as_dict: bool = False): ... + def import_keyset(self, keyset) -> None: ... + @classmethod + def from_json(cls, keyset): ... + def get_key(self, kid): ... + def get_keys(self, kid): ... diff --git a/stubs/jwcrypto/jwcrypto/jws.pyi b/stubs/jwcrypto/jwcrypto/jws.pyi new file mode 100644 index 000000000000..d1bb2f8a2c70 --- /dev/null +++ b/stubs/jwcrypto/jwcrypto/jws.pyi @@ -0,0 +1,52 @@ +from _typeshed import Incomplete + +from jwcrypto.common import JWException + +JWSHeaderRegistry: Incomplete +default_allowed_algs: Incomplete + +class InvalidJWSSignature(JWException): + def __init__(self, message: str | None = None, exception: BaseException | None = None) -> None: ... + +class InvalidJWSObject(JWException): + def __init__(self, message: str | None = None, exception: BaseException | None = None) -> None: ... + +class InvalidJWSOperation(JWException): + def __init__(self, message: str | None = None, exception: BaseException | None = None) -> None: ... + +class JWSCore: + alg: Incomplete + engine: Incomplete + key: Incomplete + header: Incomplete + protected: Incomplete + payload: Incomplete + def __init__(self, alg, key, header, payload, algs: Incomplete | None = None) -> None: ... + def sign(self): ... + def verify(self, signature): ... + +class JWS: + objects: Incomplete + verifylog: Incomplete + header_registry: Incomplete + def __init__(self, payload: Incomplete | None = None, header_registry: Incomplete | None = None) -> None: ... + @property + def allowed_algs(self): ... + @allowed_algs.setter + def allowed_algs(self, algs) -> None: ... + @property + def is_valid(self): ... + def verify(self, key, alg: Incomplete | None = None, detached_payload: Incomplete | None = None) -> None: ... + def deserialize(self, raw_jws, key: Incomplete | None = None, alg: Incomplete | None = None) -> None: ... + def add_signature( + self, key, alg: Incomplete | None = None, protected: Incomplete | None = None, header: Incomplete | None = None + ) -> None: ... + def serialize(self, compact: bool = False): ... + @property + def payload(self): ... + def detach_payload(self) -> None: ... + @property + def jose_header(self): ... + @classmethod + def from_jose_token(cls, token): ... + def __eq__(self, other: object) -> bool: ... diff --git a/stubs/jwcrypto/jwcrypto/jwt.pyi b/stubs/jwcrypto/jwcrypto/jwt.pyi new file mode 100644 index 000000000000..57f1b69c955f --- /dev/null +++ b/stubs/jwcrypto/jwcrypto/jwt.pyi @@ -0,0 +1,76 @@ +from _typeshed import Incomplete +from collections.abc import Mapping + +from jwcrypto.common import JWException, JWKeyNotFound +from jwcrypto.jwk import JWK, JWKSet + +JWTClaimsRegistry: Mapping[str, str] +JWT_expect_type: bool + +class JWTExpired(JWException): + def __init__(self, message: str | None = None, exception: BaseException | None = None) -> None: ... + +class JWTNotYetValid(JWException): + def __init__(self, message: str | None = None, exception: BaseException | None = None) -> None: ... + +class JWTMissingClaim(JWException): + def __init__(self, message: str | None = None, exception: BaseException | None = None) -> None: ... + +class JWTInvalidClaimValue(JWException): + def __init__(self, message: str | None = None, exception: BaseException | None = None) -> None: ... + +class JWTInvalidClaimFormat(JWException): + def __init__(self, message: str | None = None, exception: BaseException | None = None) -> None: ... + +class JWTMissingKeyID(JWException): + def __init__(self, message: str | None = None, exception: BaseException | None = None) -> None: ... + +class JWTMissingKey(JWKeyNotFound): + def __init__(self, message: str | None = None, exception: BaseException | None = None) -> None: ... + +class JWT: + deserializelog: Incomplete + def __init__( + self, + header: dict[Incomplete, Incomplete] | str | None = None, + claims: dict[Incomplete, Incomplete] | str | None = None, + jwt: Incomplete | None = None, + key: JWK | JWKSet | None = None, + algs: Incomplete | None = None, + default_claims: Incomplete | None = None, + check_claims: Incomplete | None = None, + expected_type: Incomplete | None = None, + ) -> None: ... + @property + def header(self): ... + @header.setter + def header(self, h) -> None: ... + @property + def claims(self): ... + @claims.setter + def claims(self, data) -> None: ... + @property + def token(self): ... + @token.setter + def token(self, t) -> None: ... + @property + def leeway(self): ... + @leeway.setter + def leeway(self, lwy) -> None: ... + @property + def validity(self): ... + @validity.setter + def validity(self, v) -> None: ... + @property + def expected_type(self): ... + @expected_type.setter + def expected_type(self, v) -> None: ... + def norm_typ(self, val): ... + def make_signed_token(self, key) -> None: ... + def make_encrypted_token(self, key) -> None: ... + def validate(self, key) -> None: ... + def deserialize(self, jwt, key: Incomplete | None = None) -> None: ... + def serialize(self, compact: bool = True): ... + @classmethod + def from_jose_token(cls, token): ... + def __eq__(self, other: object) -> bool: ... From a2ca49a2739a4bbbabea117b9b082a6a0b1b9a69 Mon Sep 17 00:00:00 2001 From: Kai Mueller Date: Mon, 23 Sep 2024 11:41:45 +0000 Subject: [PATCH 2/5] Improve --- stubs/jwcrypto/@tests/stubtest_allowlist.txt | 3 ++ stubs/jwcrypto/METADATA.toml | 1 + stubs/jwcrypto/jwcrypto/jwk.pyi | 34 +++++++------------- 3 files changed, 15 insertions(+), 23 deletions(-) create mode 100644 stubs/jwcrypto/@tests/stubtest_allowlist.txt diff --git a/stubs/jwcrypto/@tests/stubtest_allowlist.txt b/stubs/jwcrypto/@tests/stubtest_allowlist.txt new file mode 100644 index 000000000000..f1b2839df14c --- /dev/null +++ b/stubs/jwcrypto/@tests/stubtest_allowlist.txt @@ -0,0 +1,3 @@ +# test code does not need type hints +jwcrypto.tests +jwcrypto.tests-cookbook diff --git a/stubs/jwcrypto/METADATA.toml b/stubs/jwcrypto/METADATA.toml index 9945697aaa2a..53d468ec6b59 100644 --- a/stubs/jwcrypto/METADATA.toml +++ b/stubs/jwcrypto/METADATA.toml @@ -1,2 +1,3 @@ version = "1.5.*" upstream_repository = "https://github.com/latchset/jwcrypto" +requires = ["cryptography"] diff --git a/stubs/jwcrypto/jwcrypto/jwk.pyi b/stubs/jwcrypto/jwcrypto/jwk.pyi index 94fdc4b37952..14a4d839da39 100644 --- a/stubs/jwcrypto/jwcrypto/jwk.pyi +++ b/stubs/jwcrypto/jwcrypto/jwk.pyi @@ -1,8 +1,18 @@ from _typeshed import Incomplete -from collections.abc import Iterator, Sequence +from collections.abc import Sequence from enum import Enum from typing import Any, NamedTuple +from cryptography.hazmat.primitives.asymmetric.ed448 import Ed448PrivateKey as Ed448PrivateKey, Ed448PublicKey as Ed448PublicKey +from cryptography.hazmat.primitives.asymmetric.ed25519 import ( + Ed25519PrivateKey as Ed25519PrivateKey, + Ed25519PublicKey as Ed25519PublicKey, +) +from cryptography.hazmat.primitives.asymmetric.x448 import X448PrivateKey as X448PrivateKey, X448PublicKey as X448PublicKey +from cryptography.hazmat.primitives.asymmetric.x25519 import ( + X25519PrivateKey as X25519PrivateKey, + X25519PublicKey as X25519PublicKey, +) from jwcrypto.common import JWException class UnimplementedOKPCurveKey: @@ -14,15 +24,7 @@ class UnimplementedOKPCurveKey: def from_private_bytes(cls, *args) -> None: ... ImplementedOkpCurves: Sequence[str] -Ed25519PublicKey = UnimplementedOKPCurveKey -Ed25519PrivateKey = UnimplementedOKPCurveKey -Ed448PublicKey = UnimplementedOKPCurveKey -Ed448PrivateKey = UnimplementedOKPCurveKey priv_bytes: Incomplete -X25519PublicKey = UnimplementedOKPCurveKey -X25519PrivateKey = UnimplementedOKPCurveKey -X448PublicKey = UnimplementedOKPCurveKey -X448PrivateKey = UnimplementedOKPCurveKey JWKTypesRegistry: Incomplete @@ -98,24 +100,10 @@ class JWK(dict[str, Any]): def from_pem(cls, data, password: Incomplete | None = None): ... def thumbprint(self, hashalg=...): ... def thumbprint_uri(self, hname: str = "sha-256"): ... - def __setitem__(self, item, value) -> None: ... - def update(self, *args, **kwargs) -> None: ... - def setdefault(self, key, default: Incomplete | None = None): ... - def __delitem__(self, item) -> None: ... - def __eq__(self, other: object) -> bool: ... - def __hash__(self): ... - def __getattr__(self, item: str): ... - def __setattr__(self, item: str, value) -> None: ... @classmethod def from_password(cls, password): ... class JWKSet(dict[str, Any]): - def __init__(self, *args: Any, **kwargs: Any) -> None: ... - def __iter__(self) -> Iterator[Any]: ... - def __contains__(self, key) -> bool: ... - def __setitem__(self, key: str, val: Any) -> None: ... - def update(self, *args, **kwargs) -> None: ... - def setdefault(self, key: str, default: Incomplete | None = None): ... def add(self, elem) -> None: ... def export(self, private_keys: bool = True, as_dict: bool = False): ... def import_keyset(self, keyset) -> None: ... From b865b074548e42c42f556dae7cd9f54a46493e40 Mon Sep 17 00:00:00 2001 From: Kai Mueller Date: Mon, 23 Sep 2024 11:47:23 +0000 Subject: [PATCH 3/5] Fix --- stubs/jwcrypto/jwcrypto/jwk.pyi | 2 ++ stubs/jwcrypto/jwcrypto/jwt.pyi | 2 ++ 2 files changed, 4 insertions(+) diff --git a/stubs/jwcrypto/jwcrypto/jwk.pyi b/stubs/jwcrypto/jwcrypto/jwk.pyi index 14a4d839da39..c86ff358d0cd 100644 --- a/stubs/jwcrypto/jwcrypto/jwk.pyi +++ b/stubs/jwcrypto/jwcrypto/jwk.pyi @@ -102,6 +102,7 @@ class JWK(dict[str, Any]): def thumbprint_uri(self, hname: str = "sha-256"): ... @classmethod def from_password(cls, password): ... + def setdefault(self, key: str, default: Incomplete | None = None): ... class JWKSet(dict[str, Any]): def add(self, elem) -> None: ... @@ -111,3 +112,4 @@ class JWKSet(dict[str, Any]): def from_json(cls, keyset): ... def get_key(self, kid): ... def get_keys(self, kid): ... + def setdefault(self, key: str, default: Incomplete | None = None): ... diff --git a/stubs/jwcrypto/jwcrypto/jwt.pyi b/stubs/jwcrypto/jwcrypto/jwt.pyi index 57f1b69c955f..4bd2a5b79144 100644 --- a/stubs/jwcrypto/jwcrypto/jwt.pyi +++ b/stubs/jwcrypto/jwcrypto/jwt.pyi @@ -1,5 +1,6 @@ from _typeshed import Incomplete from collections.abc import Mapping +from typing_extensions import deprecated from jwcrypto.common import JWException, JWKeyNotFound from jwcrypto.jwk import JWK, JWKSet @@ -22,6 +23,7 @@ class JWTInvalidClaimValue(JWException): class JWTInvalidClaimFormat(JWException): def __init__(self, message: str | None = None, exception: BaseException | None = None) -> None: ... +@deprecated("") class JWTMissingKeyID(JWException): def __init__(self, message: str | None = None, exception: BaseException | None = None) -> None: ... From 6c0cd7ed39af2cdc3b34aacd33587a8302e13447 Mon Sep 17 00:00:00 2001 From: Kai Mueller Date: Mon, 23 Sep 2024 11:50:26 +0000 Subject: [PATCH 4/5] Fix --- stubs/jwcrypto/@tests/stubtest_allowlist.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/stubs/jwcrypto/@tests/stubtest_allowlist.txt b/stubs/jwcrypto/@tests/stubtest_allowlist.txt index f1b2839df14c..10f855e9e871 100644 --- a/stubs/jwcrypto/@tests/stubtest_allowlist.txt +++ b/stubs/jwcrypto/@tests/stubtest_allowlist.txt @@ -1,3 +1,6 @@ # test code does not need type hints jwcrypto.tests jwcrypto.tests-cookbook + +# even if the deprecated decorator is applied, the attribute is not present +jwcrypto.jwt.JWTMissingKeyID.__deprecated__ From c8fcc53e43318191dc517bf74bc7f424a8bafc46 Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Tue, 24 Sep 2024 10:07:13 +0200 Subject: [PATCH 5/5] Trailing comma --- pyrightconfig.stricter.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyrightconfig.stricter.json b/pyrightconfig.stricter.json index 0fd90bed0e85..6c00f5ed3ad2 100644 --- a/pyrightconfig.stricter.json +++ b/pyrightconfig.stricter.json @@ -100,7 +100,7 @@ "stubs/ttkthemes", "stubs/vobject", "stubs/workalendar", - "stubs/wurlitzer" + "stubs/wurlitzer", ], "typeCheckingMode": "strict", // TODO: Complete incomplete stubs