Skip to content

fix: Incorrect Token, TokenBackend typing #889

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

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

khvn26
Copy link

@khvn26 khvn26 commented Mar 13, 2025

Closes #787.

This PR aims to fix typing for the user-facing parts of tokens.Token, backends.TokenBackend classes:

  1. Added The RawToken type to replace the erroneous "Token" annotation.
  2. Expanded the incoming raw token type assumption to bytes | str, given the JWT backends support both.

I also added annotations for importable settings.

Copy link
Member

@Andrew-Chen-Wang Andrew-Chen-Wang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the PR

@@ -24,6 +23,8 @@
except ImportError:
JWK_CLIENT_AVAILABLE = False

RawToken = Union[bytes, str]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hm i wish there was a way to customize the typing based on the version of JWT.

Specifically, I wonder if we can import something consistent from PyJWT itself that represents the token. Using a union is also not entirely correct (better than what it was before for sure).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using a union is also not entirely correct

It is annotated as this exact union in the recent PyJWT versions.

FWIW, bytes | str is also technically supported since 1.7.1 despite the formal jwt: str annotation — see https://github.com/jpadilla/pyjwt/blob/b65e1ac6dc4d11801f3642eaab34ae6a54162c18/jwt/api_jws.py#L171-L177

if self.algorithm.startswith("HS"):
return self.prepared_signing_key

if self.jwks_client:
try:
if isinstance(token, bytes):
token = token.decode("utf-8")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do both v1.7.1 and v2.x versions of JWT expect the token to be string? I can understand v2, but how about v1?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1.7.1 does not implement a PyJWKClient, forcing self.jwks_client to always be None.

Annoyingly, 2.x PyJWKClient.get_signing_key_from_jwt has an incorrect annotation and can actually handle the union type as it wraps code referenced in my other comment. To avoid an extra decode call, I'd just cast it to str until the upstream issue is resolved.

Copy link
Member

@Andrew-Chen-Wang Andrew-Chen-Wang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fwiw, this makes sense to fix mypy. Thanks for fixing this + the investigation!

@Andrew-Chen-Wang
Copy link
Member

Andrew-Chen-Wang commented Mar 16, 2025

TODO it seems like we don't have a mypy and pyright type checking step in the CI. It can be added in two ways:

  • pre-commit
  • separate CI pipeline with a matrix across Python versions (probably using tox is sufficient)

I think either approach is fine, though pre-commit seems easier. This doesn't need to be added to this PR

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.

Incorrect type hints for several classes/methods
2 participants