-
-
Notifications
You must be signed in to change notification settings - Fork 694
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
Fix type annotation for decode()
/encode()
's parameter key
#605
Conversation
@jdufresne since you worked in some of the typing stuff recently, thoughts on this change? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are there existing tests that cover type bytes? If not, they should be added.
9604b18
to
d604ee7
Compare
Please note that there are even more types that some of the algorithms accept for the |
I have no idea how to properly use them in the type annotations. Everything I've tried so far resulted some error by mypy. This should work but would probably result in if MYPY:
from cryptography.hazmat.primitives.asymmetric.ec import EllipticCurvePrivateKey
def prepare(key: Union[str, bytes, "EllipticCurvePrivateKey"]):
pass |
Personally I would be okay with just reverting to Any. |
I'm just checking to see if this relates to a change I was going to make with decode not accepting bytes, but the quoted Python should be expressed as the following: # so KEY_TYPES is not needed at runtime and doesn't break because it's in the TYPE_CHECKING block.
# The constant could be define outside of the block and this future import would not be needed
from __future__ import annotations
from typing import TYPE_CHECKING
if TYPE_CHECKING:
try:
from cryptography.hazmat.primitives.asymmetric.ec import EllipticCurvePrivateKey
KEY_TYPES = Union[str, bytes, EllipticCurvePrivateKey]
except ImportError:
KEY_TYPES = Union[str, bytes]
def prepare(key: KEY_TYPES): ... If you need this to be dynamic you could do the following: _KEY_TYPES = [str, bytes]
# import 1
_KEY_TYPES.append(...)
# import 2
_KEY_TYPES.append(...)
KEY_TYPES = Union[tuple(_KEY_TYPES)] This works because |
It looks like this change is adjacent, but not the change I was looking to make. |
Your first example leads to
Also I don't think that something like |
Hmm good point. I hadn't completely thought about that and I was going off what I did (a while ago) without testing mypy. At this point I've changed the original type declaration and am playing with getting mypy running so I mainly came here for #605 (comment) but if you're not able to import or type against a concrete type I'm assuming you'd need to type with a protocol, but that only comes in Python 3.8.
It looks like it's on typeshed but it might make sense to declare a common base for private keys https://github.com/python/typeshed/blob/master/stubs/cryptography/cryptography/hazmat/primitives/asymmetric/ec.pyi so that way protocols could be used before Python 3.8. It might be possible to type with Protocols keeping everything behind Anyways, it does sound like it should just be typed as |
It looks like |
@jdufresne any suggestions on how to proceed? |
I believe the consensus here would be to use Lines 217 to 224 in 587997e
Any )
Looking at the API closer it looks like algorithms are puggable here pyjwt.jwt.algorithms which means the API cannot be type safe. A algorithm will |
@michael-k @jpadilla I think this PR should be changed to use At present, even the simple sample codes in the specification gives mypy warnings. |
I've changed the type annotation to |
@@ -76,7 +76,7 @@ def get_algorithms(self): | |||
def encode( | |||
self, | |||
payload: bytes, | |||
key: str, | |||
key: Any, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why don't you set a default value for encode
as well as decode
?
key: Any, | |
key: Any = b"", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- This PR doesn't set any default value, it just changes the one for
decode
. - The suggested change would lead to “insecure by default”
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The omission of the key does not result in signing with the empty string as the private key, and from the perspective of consistency of API design, my suggestion has some validity. But, anyway, I understood. You don't need to fix it.
@@ -37,7 +37,7 @@ def _get_default_options() -> Dict[str, Union[bool, List[str]]]: | |||
def encode( | |||
self, | |||
payload: Dict[str, Any], | |||
key: str, | |||
key: Any, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
key: Any, | |
key: Any = b"", |
@michael-k One last thing: I think you should update https://github.com/jpadilla/pyjwt/blob/master/docs/api.rst. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also, please rebase
bump - this is still an issue |
I've rebased, but I don't seem to be able to re-open this PR. |
Hi @michael-k, @auvipy, |
See #602 for details.
The issue suggests that the parameter
key
should not acceptstr
. I've not included this for backwards compatibility and because I'm not sure if that's really necessary.Closes #602