Skip to content

Document how to write test-cases for type annotations using mypy (in subprocess) #11506

Closed
python/typing
#1071
@sirosen

Description

@sirosen

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).

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions