Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve type annotations for the option parameter in decode methods. #969

Closed
wants to merge 1 commit into from
Closed

Conversation

codespearhead
Copy link

@codespearhead codespearhead commented Aug 1, 2024

Fixes: #869


Here's a minimal reproducible example you can try at the MyPy Playground.

#
# File: jwt/types.py
#

from typing import TypedDict, List

class JwtOptions(TypedDict):
    verify_signature: bool
    verify_exp: bool
    verify_nbf: bool
    verify_iat: bool
    verify_aud: bool
    verify_iss: bool
    require: List[str]

#
# File: jwt/api_jwt.py
#
# from .types import JwtOptions

class PyJWT:
    def __init__(self, options: JwtOptions | None = None) -> None:
        if options is None:
            self.options: JwtOptions = self._get_default_options()

    @staticmethod
    def _get_default_options() -> JwtOptions:
        return {
            "verify_signature": True,
            "verify_exp": True,
            "verify_nbf": True,
            "verify_iat": True,
            "verify_aud": True,
            "verify_iss": True,
            "require": [],
        }

    def decode(self, options: JwtOptions) -> None:
        pass

#
# Demo
#

pyJWT = PyJWT()

# Happy Path
# Success: no issues found in 1 source file
#
# pyJWT.decode(options={
#     'verify_signature': True,
#     'verify_exp': True,
#     'verify_nbf': True,
#     'verify_iat': True,
#     'verify_aud': True,
#     'verify_iss': True,
#     'require': []
# })

# Unhappy Path
# main.py:65: error: Missing key "require" for TypedDict "JwtOptions"  [typeddict-item]
# main.py:65: error: Extra key "required" for TypedDict "JwtOptions"  [typeddict-unknown-key]
# Found 2 errors in 1 file (checked 1 source file)
#
pyJWT.decode(options={
    'verify_signature': True,
    'verify_exp': True,
    'verify_nbf': True,
    'verify_iat': True,
    'verify_aud': True,
    'verify_iss': True,
    'required': [] # misspelled key
})

Signed-off-by: Pedro Aguiar contact@codespearhead.com

@codespearhead codespearhead marked this pull request as draft August 1, 2024 20:13
@codespearhead codespearhead marked this pull request as ready for review August 1, 2024 20:28
@codespearhead codespearhead marked this pull request as draft August 1, 2024 21:42
The options parameter currently accepts any key-value pair so long as the key is of type string (`options: dict[str, Any] | None = None`) and overwrites the default values with the arguments, as opposed to being limited to a strict set of keys and values (see [TypedDict](https://typing.readthedocs.io/en/latest/spec/typeddict.html#class-based-syntax)).

Fixes: #869

***

Here's a minimal reproducible example you can try at the [MyPy Playground](https://mypy-play.net/?mypy=latest&python=3.12).

```python

from typing import TypedDict, List

class JwtOptions(TypedDict):
    verify_signature: bool
    verify_exp: bool
    verify_nbf: bool
    verify_iat: bool
    verify_aud: bool
    verify_iss: bool
    require: List[str]

class PyJWT:
    def __init__(self, options: JwtOptions | None = None) -> None:
        if options is None:
            self.options: JwtOptions = self._get_default_options()

    @staticmethod
    def _get_default_options() -> JwtOptions:
        return {
            "verify_signature": True,
            "verify_exp": True,
            "verify_nbf": True,
            "verify_iat": True,
            "verify_aud": True,
            "verify_iss": True,
            "require": [],
        }

    def decode(self, options: JwtOptions) -> None:
        pass

pyJWT = PyJWT()

pyJWT.decode(options={
    'verify_signature': True,
    'verify_exp': True,
    'verify_nbf': True,
    'verify_iat': True,
    'verify_aud': True,
    'verify_iss': True,
    'required': [] # misspelled key
})
```

Signed-off-by: Pedro Aguiar <contact@codespearhead.com>
@codespearhead codespearhead closed this by deleting the head repository Aug 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Validate the options passed in to jwt.decode
1 participant