-
Notifications
You must be signed in to change notification settings - Fork 504
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
Add more precise type annotations for Python 3.8+ #533
Conversation
I am interested in merging this, but I am not sure it works preperly.
where the developer meant to use The
That is, without all parameters that are not used for the ECB mode. However, even if I do so, I cannot make |
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 type definition for new()
can be reduced based on which parameter each cipher mode needs.
counter : Dict = ..., | ||
use_aesni : bool = ...) -> \ | ||
EcbMode: ... | ||
|
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.
@overload
def new(key: Buffer,
mode: MODE_ECB,
use_aesni : bool = ...) -> \
EcbMode: ...
counter : Dict = ..., | ||
use_aesni : bool = ...) -> \ | ||
CbcMode: ... | ||
|
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.
@overload
def new(key: Buffer,
mode: MODE_CBC,
iv : Buffer = ...,
IV : Buffer = ...,
use_aesni : bool = ...) -> \
CbcMode: ...
counter : Dict = ..., | ||
use_aesni : bool = ...) -> \ | ||
CfbMode: ... | ||
|
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.
@overload
def new(key: Buffer,
mode: MODE_CFB,
iv : Buffer = ...,
IV : Buffer = ...,
segment_size : int = ...,
use_aesni : bool = ...) -> \
CfbMode: ...
counter : Dict = ..., | ||
use_aesni : bool = ...) -> \ | ||
OfbMode: ... | ||
|
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.
@overload
def new(key: Buffer,
mode: MODE_OFB,
iv : Buffer = ...,
IV : Buffer = ...,
use_aesni : bool = ...) -> \
OfbMode: ...
initial_value : Union[int, Buffer] = ..., | ||
counter : Dict = ..., | ||
use_aesni : bool = ...) -> \ | ||
CtrMode: ... |
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.
@overload
def new(key: Buffer,
mode: MODE_CTR,
nonce : Buffer = ...,
initial_value : Union[int, Buffer] = ...,
counter : Dict = ...,
use_aesni : bool = ...) -> \
CtrMode: ...
initial_value : Union[int, Buffer] = ..., | ||
counter : Dict = ..., | ||
use_aesni : bool = ...) -> \ | ||
EaxMode: ... |
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.
@overload
def new(key: Buffer,
mode: MODE_EAX,
nonce : Buffer = ...,
mac_len : int = ...,
use_aesni : bool = ...) -> \
EaxMode: ...
initial_value : Union[int, Buffer] = ..., | ||
counter : Dict = ..., | ||
use_aesni : bool = ...) -> \ | ||
SivMode: ... |
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.
@overload
def new(key: Buffer,
mode: MODE_SIV,
nonce : Buffer = ...,
use_aesni : bool = ...) -> \
SivMode: ...
initial_value : Union[int, Buffer] = ..., | ||
counter : Dict = ..., | ||
use_aesni : bool = ...) -> \ | ||
GcmMode: ... |
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.
@overload
def new(key: Buffer,
mode: MODE_GCM,
nonce : Buffer = ...,
mac_len : int = ...,
use_aesni : bool = ...) -> \
GcmMode: ...
initial_value : Union[int, Buffer] = ..., | ||
counter : Dict = ..., | ||
use_aesni : bool = ...) -> \ | ||
OcbMode: ... |
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.
@overload
def new(key: Buffer,
mode: MODE_OCB,
nonce : Buffer = ...,
mac_len : int = ...,
use_aesni : bool = ...) -> \
OcbMode: ...
|
||
AESMode = Union[ | ||
MODE_ECB, |
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.
Is AESMode
needed?
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.
No, it's not needed. But in the absence of an enum, it serves as a kind of grouping that I think helps make the code somewhat self-documenting.
Any updates on this issue? |
I just forgot about it @subhamagr. @Legrandin I admittedly don't know enough about crypto to know which options are needed for each mode. Thanks for the suggestions. Is there a better way to annotate |
@gwerbin Thank you for your work on this issue. I am type annotating my old project right now and stumbled into this issue. I came here to make this very pull request. I'm glad I found your PR before I started working on it. I hope these changes get committed and the PR is accepted soon! Let me know if you need any help with it! |
Small reminder for people interested in this feature that the following error will still not be caught by mypy:
I tried to tweak the type definition a few times, but with no success... |
As a note to the future, the biggest problem was that Despite that, the definition:
leads to the following revealed type:
instead of the desired:
Therefore, the following expression is still not being seen as an error:
The only solution seems to be to repeat
which is not great. Same for the other modes. |
Merged with b1794ca. Thanks! |
Much appreciated 🙌 When can we expect this to be released with |
Hello,
AES.new
returns aUnion
type, which means that a type checker like Mypy cannot know which type exactly is returned. This is a problem if you want to use an attribute that is present on some members of the union but not other members.For example,
CbcMode
has aniv
attribute, butEcbMode
does not. Therefore this code will not type check:On Python 3.8 and above, we can solve this problem with
typing.Literal
andtyping.overload
.I also replaced
Union[bytes, bytearray, memoryview]
withByteString
, but if there is a specific reason to use the former I can change it back.Apologies if I have not followed proper contribution procedures. I didn't see a contributor guide in the repository.
Edit: I see similar issues with several of the other
Crypto.Cipher
type stubs, e.g. https://github.com/gwerbin/pycryptodome/blob/master/lib/Crypto/Cipher/DES.pyi. I am happy to extend this PR to include the others if the maintainers want to proceed.