A Pytest Plugin for Mypy static type checking integration
npx @tessl/cli install tessl/pypi-pytest-mypy@1.0.0A pytest plugin that seamlessly integrates the mypy static type checker into pytest test runs, enabling automatic type checking of Python source files as part of the testing process. This plugin extends pytest with mypy-specific command-line flags and creates type checking test items that execute alongside regular tests, helping developers catch type-related issues early in the development cycle.
pip install pytest-mypyimport pytest_mypyThe plugin is automatically registered via pytest's entry point system when installed:
# Entry point registration in pyproject.toml
[project.entry-points.pytest11]
mypy = "pytest_mypy"No explicit imports are required for basic usage.
# Enable mypy checking with pytest
# Command line usage:
# pytest --mypy src/
# Configure in conftest.py for programmatic control
def pytest_configure(config):
plugin = config.pluginmanager.getplugin('mypy')
plugin.mypy_argv.append('--check-untyped-defs')
plugin.mypy_argv.append('--ignore-missing-imports')The plugin operates through pytest's hook system and creates specialized test items:
Comprehensive command-line interface for controlling mypy behavior within pytest, including error reporting styles, configuration files, and failure handling modes.
def pytest_addoption(parser: pytest.Parser) -> None:
"""Add mypy-specific command line options to pytest."""
def pytest_configure(config: pytest.Config) -> None:
"""Initialize plugin configuration and register sub-plugins based on options."""Available options:
--mypy: Enable mypy checking--mypy-ignore-missing-imports: Suppress import resolution errors--mypy-config-file: Specify custom mypy configuration file--mypy-report-style: Choose error output format--mypy-no-status-check: Ignore mypy exit status--mypy-xfail: Mark mypy errors as expected failuresSpecialized pytest test items for mypy type checking that integrate with pytest's collection, execution, and reporting systems.
class MypyFileItem(MypyItem):
"""Test item for mypy errors in a specific file."""
def runtest(self) -> None: ...
def reportinfo(self) -> Tuple[Path, None, str]: ...
class MypyStatusItem(MypyItem):
"""Test item for overall mypy exit status validation."""
def runtest(self) -> None: ...Efficient caching system for mypy execution results, supporting both single-process and xdist parallel execution modes.
class MypyResults:
"""Parsed and cached mypy execution results."""
opts: List[str]
args: List[str]
stdout: str
stderr: str
status: int
path_lines: Dict[Optional[Path], List[str]]
@classmethod
def from_mypy(cls, paths: List[Path], *, opts: Optional[List[str]] = None) -> MypyResults: ...
@classmethod
def from_session(cls, session: pytest.Session) -> MypyResults: ...Runtime configuration capabilities through conftest.py for advanced mypy customization and formatter overrides.
# Global configuration variables
mypy_argv: List[str]
test_name_formatter: Callable[[MypyFileItem], str]
file_error_formatter: Callable[[MypyItem, MypyResults, List[str]], str]class MypyError(Exception):
"""Exception raised when mypy finds type checking violations."""
@dataclass(frozen=True)
class MypyConfigStash:
"""Plugin data stored in pytest.Config stash."""
mypy_results_path: Path
@classmethod
def from_serialized(cls, serialized: str) -> MypyConfigStash: ...
def serialized(self) -> str: ...
class MypyFile(pytest.File):
"""File collector that generates mypy test items."""
def collect(self) -> Iterator[MypyItem]: ...
class MypyCollectionPlugin:
"""Plugin that collects MypyFile instances during pytest collection."""
def pytest_collect_file(self, file_path: Path, parent: pytest.Collector) -> Optional[MypyFile]: ...
# Global configuration variables
mypy_argv: List[str] # Global mypy command line arguments
test_name_formatter: Callable[[MypyFileItem], str] # Test name formatting function
file_error_formatter: Callable[[MypyItem, MypyResults, List[str]], str] # Error formatting function
item_marker: str # Marker name for mypy test items ("mypy")
nodeid_name: str # Base node ID name ("mypy")
terminal_summary_title: str # Terminal summary section title ("mypy")
# Stash keys for configuration storage
stash_key: Dict[str, pytest.StashKey]
def _error_severity(line: str) -> Optional[str]:
"""Extract error severity level from mypy output line."""
# Plugin classes for xdist support
class MypyXdistControllerPlugin:
"""Plugin active only on xdist controller processes."""
def pytest_configure_node(self, node: WorkerController) -> None: ...
class MypyControllerPlugin:
"""Plugin for main/controller processes (not xdist workers)."""
def pytest_terminal_summary(self, terminalreporter: TerminalReporter, config: pytest.Config) -> None: ...
def pytest_unconfigure(self, config: pytest.Config) -> None: ...