Description
Documentation
When writing a python package which publishes type information, it's very easy to mess up the annotations you present to your users. For example, a decorator can easily lose type information if written carelessly:
def mydeco(f: Callable) -> Callable:
...
The solution, "obviously", is to test your annotations. But how?
Although there are several packages which add pytest-mypy integrations, there is no guidance from mypy
.
I propose the addition of a new doc on "testing package annotations" in the miscellaneous section, which demonstrates a simple test helper which writes provided code to files and runs mypy
on those files, for use with test suites.
To seed things, here's what I wrote recently to do this:
import os
import re
import pytest
# mypy's only python-callable API
# see:
# https://mypy.readthedocs.io/en/stable/extending_mypy.html#integrating-mypy-into-another-python-application
from mypy import api as mypy_api
@pytest.fixture
def _in_tmp_path(tmp_path):
cur = os.getcwd()
try:
os.chdir(tmp_path)
yield
finally:
os.chdir(cur)
@pytest.fixture
def run_reveal_type(tmp_path, _in_tmp_path):
content_path = tmp_path / "reveal_type_test.py"
def func(code_snippet, *, preamble: str = ""):
content_path.write_text(preamble + f"reveal_type({code_snippet})")
result = mypy_api.run(["reveal_type_test.py"])
stdout = result[0]
# mypy reveal_type shows notes like
# note: Revealed type is "Union[builtins.str, None]"
# find and extract with a regex
match = re.search(r'note: Revealed type is "([^"]+)"', stdout)
assert match is not None
return match.group(1)
return func
I'm leveraging pytest
's fixture system here, but I'd be happy to write the necessary tmpdir bits to make this compatible with unittest or other frameworks.
I would be enthusiastic about documenting this and putting together a PR, provided that the maintainers here like the idea (and find the proposed testing helper to document acceptable).