CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-pytest-mypy

A Pytest Plugin for Mypy static type checking integration

Pending
Overview
Eval results
Files

configuration.mddocs/

Configuration

Runtime configuration capabilities for customizing mypy integration behavior through conftest.py and global variables. Provides programmatic control over mypy execution, error formatting, and test naming.

Capabilities

Global Configuration Variables

Direct access to plugin configuration through global variables that can be modified at runtime.

# Global mypy command line arguments
mypy_argv: List[str]
"""
Global list of mypy command line arguments.

Automatically populated from pytest command line options and can be
extended programmatically in conftest.py for additional mypy configuration.

Example modifications:
- mypy_argv.append('--check-untyped-defs')
- mypy_argv.extend(['--strict', '--warn-redundant-casts'])
"""

# Test name formatting function
test_name_formatter: Callable[[MypyFileItem], str]
"""
Function used to format test names in pytest reports.

Default implementation shows "[mypy] relative/path/to/file.py".
Can be replaced with custom formatter for different naming schemes.

Parameters:
- item: MypyFileItem being formatted

Returns:
Formatted test name string for display in reports
"""

# File error formatting function  
file_error_formatter: Callable[[MypyItem, MypyResults, List[str]], str]
"""
Function used to format mypy error messages for display.

Default implementation respects --mypy-report-style setting.
Can be replaced with custom formatter for specialized error display.

Parameters:
- item: MypyItem that encountered errors
- results: Complete MypyResults from execution
- lines: List of error lines for this item

Returns:
Formatted error message string for display
"""

Default Formatters

Built-in formatter functions that can be used or replaced.

def default_test_name_formatter(*, item: MypyFileItem) -> str:
    """
    Default formatter for mypy test names.
    
    Creates test names in the format "[mypy] relative/path/to/file.py"
    using the file path relative to the pytest invocation directory.
    
    Parameters:
    - item: MypyFileItem to generate name for
    
    Returns:
    Formatted test name with [mypy] prefix and relative path
    """

def default_file_error_formatter(
    item: MypyItem,
    results: MypyResults, 
    lines: List[str]
) -> str:
    """
    Default formatter for mypy error messages.
    
    Formats error lines according to --mypy-report-style setting:
    - 'mypy': Preserves original mypy output format
    - 'no-path': Strips path prefixes for cleaner display
    
    Parameters:
    - item: MypyItem that encountered the errors
    - results: Complete mypy execution results
    - lines: Error lines to format
    
    Returns:
    Formatted error message string
    """

Plugin Access Pattern

Standard pattern for accessing and configuring the mypy plugin.

def pytest_configure(config: pytest.Config) -> None:
    """
    Standard hook for configuring the mypy plugin.
    
    The plugin module can be imported directly to access
    global configuration variables and functions.
    
    Parameters:
    - config: Pytest configuration object
    """
    import pytest_mypy
    
    # Direct access to global configuration variables
    pytest_mypy.mypy_argv.extend(['--strict', '--check-untyped-defs'])
    pytest_mypy.test_name_formatter = custom_formatter
    pytest_mypy.file_error_formatter = custom_error_formatter

Configuration Constants

Plugin constants that define behavior and can be referenced for customization.

item_marker: str = "mypy"
"""Marker name applied to all mypy test items for filtering."""

nodeid_name: str = "mypy"  
"""Base node ID name used for mypy test items."""

terminal_summary_title: str = "mypy"
"""Title used in pytest terminal summary section."""

Configuration Examples

Basic Mypy Arguments Extension

# conftest.py
def pytest_configure(config):
    """Add additional mypy checking options."""
    import pytest_mypy
    
    # Enable strict type checking
    pytest_mypy.mypy_argv.extend([
        '--strict',
        '--check-untyped-defs',
        '--warn-redundant-casts',
        '--warn-unused-ignores'
    ])

Custom Test Name Formatting

# conftest.py
def pytest_configure(config):
    """Customize mypy test names for better readability."""
    import pytest_mypy
    
    def custom_test_name(*, item):
        """Show just filename instead of full path."""
        return f"[mypy] {item.path.name}"
    
    pytest_mypy.test_name_formatter = custom_test_name

Advanced Error Formatting

# conftest.py  
def pytest_configure(config):
    """Customize mypy error display format."""
    import pytest_mypy
    
    def detailed_error_formatter(item, results, lines):
        """Add context and statistics to error messages.""" 
        error_count = len(lines)
        header = f"Found {error_count} type issues in {item.path.name}:"
        
        formatted_lines = []
        for line in lines:
            # Add severity highlighting
            if "error:" in line:
                formatted_lines.append(f"❌ {line}")
            elif "warning:" in line:
                formatted_lines.append(f"⚠️  {line}")
            else:
                formatted_lines.append(f"ℹ️  {line}")
        
        return header + "\n" + "\n".join(formatted_lines)
    
    pytest_mypy.file_error_formatter = detailed_error_formatter

Conditional Configuration

# conftest.py
import os

def pytest_configure(config):
    """Configure mypy based on environment."""
    import pytest_mypy
    
    # Strict checking in CI environment
    if os.getenv('CI'):
        pytest_mypy.mypy_argv.extend([
            '--strict',
            '--warn-unreachable',
            '--disallow-any-generics'
        ])
    else:
        # More lenient for local development
        pytest_mypy.mypy_argv.extend([
            '--ignore-missing-imports',
            '--allow-redefinition'
        ])

Integration with Other Tools

# conftest.py
def pytest_configure(config):
    """Integrate mypy configuration with project settings."""
    import pytest_mypy
    
    # Use project-specific mypy configuration
    project_mypy_config = config.rootpath / "tools" / "mypy.ini"
    if project_mypy_config.exists():
        pytest_mypy.mypy_argv.append(f"--config-file={project_mypy_config}")
    
    # Custom exclusions based on pytest collection
    if hasattr(config.option, 'ignore_paths'):
        for ignore_path in config.option.ignore_paths:
            pytest_mypy.mypy_argv.append(f"--exclude={ignore_path}")

Error Handling Customization

# conftest.py
def pytest_configure(config):
    """Add custom error handling and reporting."""
    import pytest_mypy
    
    # Store original error formatter
    original_formatter = pytest_mypy.file_error_formatter
    
    def logging_error_formatter(item, results, lines):
        """Log errors to external system before displaying."""
        # Log to external monitoring system
        import logging
        logger = logging.getLogger('mypy_errors')
        logger.error(f"Type errors in {item.path}: {len(lines)} issues")
        
        # Use original formatting for display
        return original_formatter(item, results, lines)
    
    pytest_mypy.file_error_formatter = logging_error_formatter

Install with Tessl CLI

npx tessl i tessl/pypi-pytest-mypy

docs

command-line.md

configuration.md

index.md

results-management.md

test-items.md

tile.json