Using type stubs for Python stdlib with mypy

Question:

Consider the following MWE:

import hashlib


def tstfun(h: hashlib._hashlib.HASH):
    print(h)


h = hashlib.md5()
tstfun(h)
# reveal_type(h)

Running this as-is yields – no surprise:

$ python mypytest.py
<md5 _hashlib.HASH object @ 0x7fa645dedd90>

But checking this with mypy fails with:

$ mypy mypytest.py 
mypytest.py:4: error: Name 'hashlib._hashlib.HASH' is not defined
Found 1 error in 1 file (checked 1 source file)

Now, revealing the type on h (commenting in that reveal_type line):

$ mypy mypytest.py 
mypytest.py:4: error: Name 'hashlib._hashlib.HASH' is not defined
mypytest.py:10: note: Revealed type is 'hashlib._Hash'
Found 1 error in 1 file (checked 1 source file)

Well, ok, then changing the type hint from hashlib._hashlib.HASH to hashlib._Hash:

$ python mypytest.py 
Traceback (most recent call last):
  File "/radarugs/hintze/s4-cnc-tools/mypytest.py", line 4, in <module>
    def tstfun(h: hashlib._HASH):
AttributeError: module 'hashlib' has no attribute '_HASH'
$ mypy mypytest.py 
mypytest.py:4: error: Name 'hashlib._HASH' is not defined
Found 1 error in 1 file (checked 1 source file)

…which is the worst outcome.

How to check if the type stubs for the hashlib are correctly found and used by mypy? What else to check? What do I get wrong?

Asked By: hintze

||

Answers:

According to the traceback, you used hashlib._HASH.

With this code:

import hashlib

def tstfun(h: hashlib._Hash):
    print(h)

h = hashlib.md5()
tstfun(h)

Mypy reports: Success: no issues found in 1 source file

Answered By: Laurent

Using hashlib._Hash is correct, but you also need to from __future__ import annotations if you don’t want to use quotes. See https://github.com/python/typeshed/issues/2928

from __future__ import annotations
import hashlib

def tstfun(h: hashlib._Hash):
    print(h)

h = hashlib.md5()
tstfun(h)

N.B.: __future__.annotations is available starting in python 3.7.0b1. See https://docs.python.org/3/library/__future__.html

Answered By: dthor