Skip to content

Dict[str, Callable[...]] Not Handled Properly #7329

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

Closed
ameily opened this issue Aug 13, 2019 · 2 comments
Closed

Dict[str, Callable[...]] Not Handled Properly #7329

ameily opened this issue Aug 13, 2019 · 2 comments

Comments

@ameily
Copy link

ameily commented Aug 13, 2019

I'm trying to annotate a dict of supported hashing algorithms.

from typing import Callable, Optional, Dict
import hashlib
from _hashlib import HASH

#: Hash algorithm, as returned by hashlib.new()
HashAlgorithm = Callable[[Optional[bytes]], HASH]

ALGORITHMS = {
    'md5': hashlib.md5,
    'sha1': hashlib.sha1,
    'sha224': hashlib.sha224,
    'sha256': hashlib.sha256,
    'sha384': hashlib.sha384,
    'sha512': hashlib.sha512
}  # type: Dict[str, HashAlgorithm]

This is resulting in a weird / confusing error message (ignore line numbers).

file.py823: error: Dict entry 0 has incompatible type "str": "Callable[[Union[bytes, bytearray, memoryview]], _Hash]"; expected "str": "Callable[[Optional[bytes]], Any]"
file.py:823: error: Dict entry 1 has incompatible type "str": "Callable[[Union[bytes, bytearray, memoryview]], _Hash]"; expected "str": "Callable[[Optional[bytes]], Any]"
# same error for each entry in the dict

Switching the value type to just Callbable fixes the issue, but it seems to me that there's an underlying problem here.

Version info:

python -V
python 3.7.3

mypy -V
mypy 0.720
@JelleZijlstra
Copy link
Member

Isn't the issue just that your HashAlgorithm alias allows None as an argument, but the hashlib functions do not?

@ilevkivskyi
Copy link
Member

Yes, this is a legitimate error, I tried some methods and they are actually failing with None:

>>> hashlib.md5(None)
TypeError: object supporting the buffer API required

If you wanted an optional argument, not optional type, then define a callback protocol:

class HashAlgorithm(Protocol):
    def __call__(self, arg: bytes = ...) -> HASH: ...

Finally, I don't see why do you need this annotation here, mypy is able to infer a decent type itself.

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

No branches or pull requests

3 participants