Skip to content

Pytest plugin

πŸ€– AI-Generated Content

This documentation was generated with AI assistance and is still being audited. Some, or potentially a lot, of this information may be inaccurate. Learn more.

provide.testkit.pytest_plugin

Pytest plugin that disables setproctitle to prevent pytest-xdist issues on macOS.

On macOS, when setproctitle is installed, pytest-xdist's use of it to set worker process titles causes the terminal/UX to freeze completely. This plugin prevents setproctitle from being imported by using Python's import hook system.

The plugin uses sys.meta_path to intercept setproctitle imports and raise ImportError, causing pytest-xdist to gracefully fall back to its built-in no-op implementation.

This approach is clean because: - It leverages xdist's existing try/except ImportError fallback - Works in both main process and worker subprocesses automatically - Requires no manual installation or .venv modification - Uses standard Python import hook mechanism

Additionally, this plugin configures structlog with test-safe defaults BEFORE any Foundation modules are imported. This ensures that fallback loggers created during circular import resolution have proper processors and the BoundLogger wrapper class (which supports trace level logging).

Classes

SetproctitleImportBlocker

Import hook that blocks setproctitle imports by raising ImportError.

This hooks into Python's import system via sys.meta_path and intercepts any attempt to import setproctitle, causing it to fail with ImportError.

pytest-xdist has built-in fallback handling for ImportError when importing setproctitle, so this causes it to use its no-op implementation instead.

Functions
find_spec
find_spec(
    fullname: str, path: Any = None, target: Any = None
) -> Any

Block setproctitle imports or redirect to stub file.

When setproctitle is imported, this hook either: 1. Returns a ModuleSpec for the stub file (if found) - for mutmut compatibility 2. Raises ImportError to block the real package - for pytest-xdist

The stub file approach allows mutation testing tools like mutmut to import setproctitle without actually using the C extension that causes macOS freezing with pytest-xdist.

Returns:

Type Description
Any

ModuleSpec if stub file exists, otherwise raises ImportError

Source code in provide/testkit/_blocker.py
def find_spec(
    self,
    fullname: str,
    path: Any = None,
    target: Any = None,
) -> Any:
    """Block setproctitle imports or redirect to stub file.

    When setproctitle is imported, this hook either:
    1. Returns a ModuleSpec for the stub file (if found) - for mutmut compatibility
    2. Raises ImportError to block the real package - for pytest-xdist

    The stub file approach allows mutation testing tools like mutmut to
    import setproctitle without actually using the C extension that causes
    macOS freezing with pytest-xdist.

    Returns:
        ModuleSpec if stub file exists, otherwise raises ImportError
    """
    if fullname == "setproctitle":
        # DEBUG: Track setproctitle import attempts
        import os
        import tempfile
        import traceback

        _pid = os.getpid()
        _debug_file = Path(tempfile.gettempdir()) / f"testkit-debug-{_pid}.log"
        with _debug_file.open("a") as f:
            f.write(f"πŸ›πŸš« [PID {_pid}] setproctitle import BLOCKED!\n")
            f.write("πŸ›πŸ“ Stack trace:\n")
            for line in traceback.format_stack()[:-1]:
                f.write(f"  {line.strip()}\n")
            f.flush()

        # Check if there's a stub setproctitle.py in site-packages
        # If found, create a ModuleSpec to load it directly
        for sp in sys.path:
            stub_path = Path(sp) / "setproctitle.py"
            if stub_path.exists():
                # Found stub - create a ModuleSpec to force loading this file
                # This prevents Python from finding the real setproctitle package
                with _debug_file.open("a") as f:
                    f.write(f"πŸ›πŸ“ [PID {_pid}] Using stub file: {stub_path}\n")
                    f.flush()
                loader = importlib.machinery.SourceFileLoader(fullname, str(stub_path))
                spec = importlib.util.spec_from_file_location(
                    fullname, stub_path, loader=loader, submodule_search_locations=None
                )
                return spec
        # No stub found, block the real setproctitle
        with _debug_file.open("a") as f:
            f.write(f"πŸ›βŒ [PID {_pid}] No stub found, raising ImportError\n")
            f.flush()
        raise ImportError("setproctitle import blocked by provide-testkit to prevent macOS freezing")
    return None

Functions

pytest_load_initial_conftests

pytest_load_initial_conftests() -> None

Hook kept for documentation purposes.

The actual setproctitle mocking happens at module level (above), not in this hook, because hooks run too late - xdist imports setproctitle before hooks execute.

Source code in provide/testkit/pytest_plugin.py
def pytest_load_initial_conftests() -> None:
    """Hook kept for documentation purposes.

    The actual setproctitle mocking happens at module level (above),
    not in this hook, because hooks run too late - xdist imports
    setproctitle before hooks execute.
    """