summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Maurin <julian.maurin.perso@pm.me>2022-08-03 06:28:10 +0200
committerGitHub <noreply@github.com>2022-08-03 10:28:10 +0600
commitf827be366cc2560266a412697b5194ee4782b510 (patch)
tree1cbac899d121c45fb2e0fb7a9256e381c0a714a1
parente8780abdd561963e3b0ca49ecec8b8519a793f75 (diff)
downloadpyjwt-f827be366cc2560266a412697b5194ee4782b510.tar.gz
Mypy as pre-commit check + api_jws typing (#787)
* feat(mypy): from tox to pre-commit * fix(mypy): apply mypy fixes * feat(api_jws): typing Co-authored-by: JulianMaurin <julian.maurin@backmarket.com>
-rw-r--r--.pre-commit-config.yaml5
-rw-r--r--jwt/api_jws.py61
-rw-r--r--jwt/help.py13
-rw-r--r--jwt/utils.py4
-rw-r--r--pyproject.toml8
-rw-r--r--setup.cfg7
-rw-r--r--tox.ini6
7 files changed, 51 insertions, 53 deletions
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index d23a169..00b112e 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -34,3 +34,8 @@ repos:
hooks:
- id: check-manifest
args: [--no-build-isolation]
+
+ - repo: https://github.com/pre-commit/mirrors-mypy
+ rev: "v0.971"
+ hooks:
+ - id: mypy
diff --git a/jwt/api_jws.py b/jwt/api_jws.py
index 90206c9..ab8490f 100644
--- a/jwt/api_jws.py
+++ b/jwt/api_jws.py
@@ -1,8 +1,9 @@
+from __future__ import annotations
+
import binascii
import json
import warnings
-from collections.abc import Mapping
-from typing import Any, Dict, List, Optional, Type
+from typing import Any, Type
from .algorithms import (
Algorithm,
@@ -23,7 +24,7 @@ from .warnings import RemovedInPyjwt3Warning
class PyJWS:
header_typ = "JWT"
- def __init__(self, algorithms=None, options=None):
+ def __init__(self, algorithms=None, options=None) -> None:
self._algorithms = get_default_algorithms()
self._valid_algs = (
set(algorithms) if algorithms is not None else set(self._algorithms)
@@ -39,10 +40,10 @@ class PyJWS:
self.options = {**self._get_default_options(), **options}
@staticmethod
- def _get_default_options():
+ def _get_default_options() -> dict[str, bool]:
return {"verify_signature": True}
- def register_algorithm(self, alg_id, alg_obj):
+ def register_algorithm(self, alg_id: str, alg_obj: Algorithm) -> None:
"""
Registers a new Algorithm for use when creating and verifying tokens.
"""
@@ -55,7 +56,7 @@ class PyJWS:
self._algorithms[alg_id] = alg_obj
self._valid_algs.add(alg_id)
- def unregister_algorithm(self, alg_id):
+ def unregister_algorithm(self, alg_id: str) -> None:
"""
Unregisters an Algorithm for use when creating and verifying tokens
Throws KeyError if algorithm is not registered.
@@ -69,7 +70,7 @@ class PyJWS:
del self._algorithms[alg_id]
self._valid_algs.remove(alg_id)
- def get_algorithms(self):
+ def get_algorithms(self) -> list[str]:
"""
Returns a list of supported values for the 'alg' parameter.
"""
@@ -96,9 +97,9 @@ class PyJWS:
self,
payload: bytes,
key: str,
- algorithm: Optional[str] = "HS256",
- headers: Optional[Dict[str, Any]] = None,
- json_encoder: Optional[Type[json.JSONEncoder]] = None,
+ algorithm: str | None = "HS256",
+ headers: dict[str, Any] | None = None,
+ json_encoder: Type[json.JSONEncoder] | None = None,
is_payload_detached: bool = False,
) -> str:
segments = []
@@ -117,7 +118,7 @@ class PyJWS:
is_payload_detached = True
# Header
- header = {"typ": self.header_typ, "alg": algorithm_} # type: Dict[str, Any]
+ header: dict[str, Any] = {"typ": self.header_typ, "alg": algorithm_}
if headers:
self._validate_headers(headers)
@@ -165,11 +166,11 @@ class PyJWS:
self,
jwt: str,
key: str = "",
- algorithms: Optional[List[str]] = None,
- options: Optional[Dict[str, Any]] = None,
- detached_payload: Optional[bytes] = None,
+ algorithms: list[str] | None = None,
+ options: dict[str, Any] | None = None,
+ detached_payload: bytes | None = None,
**kwargs,
- ) -> Dict[str, Any]:
+ ) -> dict[str, Any]:
if kwargs:
warnings.warn(
"passing additional kwargs to decode_complete() is deprecated "
@@ -210,9 +211,9 @@ class PyJWS:
self,
jwt: str,
key: str = "",
- algorithms: Optional[List[str]] = None,
- options: Optional[Dict[str, Any]] = None,
- detached_payload: Optional[bytes] = None,
+ algorithms: list[str] | None = None,
+ options: dict[str, Any] | None = None,
+ detached_payload: bytes | None = None,
**kwargs,
) -> str:
if kwargs:
@@ -227,7 +228,7 @@ class PyJWS:
)
return decoded["payload"]
- def get_unverified_header(self, jwt):
+ def get_unverified_header(self, jwt: str | bytes) -> dict:
"""Returns back the JWT header parameters as a dict()
Note: The signature is not verified so the header parameters
@@ -238,7 +239,7 @@ class PyJWS:
return headers
- def _load(self, jwt):
+ def _load(self, jwt: str | bytes) -> tuple[bytes, bytes, dict, bytes]:
if isinstance(jwt, str):
jwt = jwt.encode("utf-8")
@@ -261,7 +262,7 @@ class PyJWS:
except ValueError as e:
raise DecodeError(f"Invalid header string: {e}") from e
- if not isinstance(header, Mapping):
+ if not isinstance(header, dict):
raise DecodeError("Invalid header string: must be a json object")
try:
@@ -278,16 +279,16 @@ class PyJWS:
def _verify_signature(
self,
- signing_input,
- header,
- signature,
- key="",
- algorithms=None,
- ):
+ signing_input: bytes,
+ header: dict,
+ signature: bytes,
+ key: str = "",
+ algorithms: list[str] | None = None,
+ ) -> None:
alg = header.get("alg")
- if algorithms is not None and alg not in algorithms:
+ if not alg or (algorithms is not None and alg not in algorithms):
raise InvalidAlgorithmError("The specified alg value is not allowed")
try:
@@ -299,11 +300,11 @@ class PyJWS:
if not alg_obj.verify(signing_input, key, signature):
raise InvalidSignatureError("Signature verification failed")
- def _validate_headers(self, headers):
+ def _validate_headers(self, headers: dict[str, Any]) -> None:
if "kid" in headers:
self._validate_kid(headers["kid"])
- def _validate_kid(self, kid):
+ def _validate_kid(self, kid: str) -> None:
if not isinstance(kid, str):
raise InvalidTokenError("Key ID header parameter must be a string")
diff --git a/jwt/help.py b/jwt/help.py
index 767c323..0c02eb9 100644
--- a/jwt/help.py
+++ b/jwt/help.py
@@ -8,7 +8,7 @@ from . import __version__ as pyjwt_version
try:
import cryptography
except ModuleNotFoundError:
- cryptography = None # type: ignore
+ cryptography = None
def info() -> Dict[str, Dict[str, str]]:
@@ -29,14 +29,15 @@ def info() -> Dict[str, Dict[str, str]]:
if implementation == "CPython":
implementation_version = platform.python_version()
elif implementation == "PyPy":
+ pypy_version_info = getattr(sys, "pypy_version_info")
implementation_version = (
- f"{sys.pypy_version_info.major}." # type: ignore[attr-defined]
- f"{sys.pypy_version_info.minor}."
- f"{sys.pypy_version_info.micro}"
+ f"{pypy_version_info.major}."
+ f"{pypy_version_info.minor}."
+ f"{pypy_version_info.micro}"
)
- if sys.pypy_version_info.releaselevel != "final": # type: ignore[attr-defined]
+ if pypy_version_info.releaselevel != "final":
implementation_version = "".join(
- [implementation_version, sys.pypy_version_info.releaselevel] # type: ignore[attr-defined]
+ [implementation_version, pypy_version_info.releaselevel]
)
else:
implementation_version = "Unknown"
diff --git a/jwt/utils.py b/jwt/utils.py
index b8ad5fa..16cae06 100644
--- a/jwt/utils.py
+++ b/jwt/utils.py
@@ -1,7 +1,7 @@
import base64
import binascii
import re
-from typing import Any, Union
+from typing import Union
try:
from cryptography.hazmat.primitives.asymmetric.ec import EllipticCurve
@@ -10,7 +10,7 @@ try:
encode_dss_signature,
)
except ModuleNotFoundError:
- EllipticCurve = Any # type: ignore
+ EllipticCurve = None
def force_bytes(value: Union[str, bytes]) -> bytes:
diff --git a/pyproject.toml b/pyproject.toml
index 8c870eb..f406505 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -2,7 +2,6 @@
requires = ["setuptools"]
build-backend = "setuptools.build_meta"
-
[tool.coverage.run]
parallel = true
branch = true
@@ -14,8 +13,13 @@ source = ["jwt", ".tox/*/site-packages"]
[tool.coverage.report]
show_missing = true
-
[tool.isort]
profile = "black"
atomic = true
combine_as_imports = true
+
+[tool.mypy]
+python_version = 3.7
+ignore_missing_imports = true
+warn_unused_ignores = true
+no_implicit_optional = true
diff --git a/setup.cfg b/setup.cfg
index 9fc9169..434e22c 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -57,7 +57,6 @@ dev =
types-cryptography>=3.3.21
pytest>=6.0.0,<7.0.0
coverage[toml]==5.0.4
- mypy
pre-commit
[options.packages.find]
@@ -67,9 +66,3 @@ exclude =
[flake8]
extend-ignore = E203, E501
-
-[mypy]
-python_version = 3.7
-ignore_missing_imports = true
-warn_unused_ignores = true
-no_implicit_optional = true
diff --git a/tox.ini b/tox.ini
index 3e8513a..07ace11 100644
--- a/tox.ini
+++ b/tox.ini
@@ -48,12 +48,6 @@ commands =
python -m doctest README.rst
-[testenv:typing]
-basepython = python3.8
-extras = dev
-commands = mypy jwt
-
-
[testenv:lint]
basepython = python3.8
extras = dev