debugging.py


Overview

The [debugging.py](/projects/286/67457) module integrates Python's interactive debugger (PDB) into the pytest testing framework, enabling automatic or manual entry into a debugging session during test execution. It provides:

This module is implemented as a pytest plugin that hooks into pytest’s lifecycle events, command line processing, and test execution to embed interactive debugging capabilities smoothly.


Detailed Explanation of Components

Functions

_validate_usepdb_cls(value: str) -> tuple[str, str]


pytest_addoption(parser: Parser) -> None


pytest_configure(config: Config) -> None


Classes

pytestPDB

A singleton-like class that manages integration with pdb, wrapping the debugger class and handling IO capturing during debugging sessions.


PdbInvoke

Plugin class that triggers pdb post-mortem debugging on test errors or internal errors.


PdbTrace

Plugin class that wraps test functions to start pdb immediately at test start (for `--trace`).


Functions for Wrapping Test Functions

wrap_pytest_function_for_tracing(pyfuncitem) -> None


maybe_wrap_pytest_function_for_tracing(pyfuncitem) -> None


Internal Functions for Post-Mortem Debugging

_enter_pdb(node: Node, excinfo: ExceptionInfo, rep: BaseReport) -> BaseReport


_postmortem_exc_or_tb(excinfo: ExceptionInfo) -> types.TracebackType | BaseException


post_mortem(tb_or_exc: types.TracebackType | BaseException) -> None


Important Implementation Details and Algorithms


Interaction with Other Modules


Usage Examples

Starting pytest with automatic debugger on failure

pytest --pdb

When a test fails or is interrupted, pytest will suspend output capturing and drop into pdb at the failure point.


Starting pytest with immediate debugging on each test

pytest --trace

Each test function is wrapped to invoke pdb at the very first statement, allowing interactive step-through from the start.


Using a custom debugger class

pytest --pdbcls=IPython.terminal.debugger:TerminalPdb

Uses IPython's debugger instead of the default pdb.


Programmatically invoking debugger in code

import pdb
pdb.set_trace()  # Actually invokes pytestPDB.set_trace during pytest runs

Mermaid Class Diagram

classDiagram
    class pytestPDB {
        +_pluginmanager: PytestPluginManager | None
        +_config: Config | None
        +_saved: list
        +_recursive_debug: int
        +_wrapped_pdb_cls: tuple | None
        +_is_capturing(capman)
        +_import_pdb_cls(capman)
        +_get_pdb_wrapper_class(pdb_cls, capman)
        +_init_pdb(method, *args, **kwargs)
        +set_trace(*args, **kwargs)
    }

    class PdbInvoke {
        +pytest_exception_interact(node, call, report)
        +pytest_internalerror(excinfo)
    }

    class PdbTrace {
        +pytest_pyfunc_call(pyfuncitem)
    }

    pytestPDB <|-- PdbInvoke : uses
    pytestPDB <|-- PdbTrace : uses

Mermaid Flowchart: Debugging Invocation Flow

flowchart TD
    Start[Test Run Start]
    CheckTrace{--trace enabled?}
    WrapTest[Wrap test function\nwith debugger]
    RunTest[Run test function]
    CheckError{Test failed or KeyboardInterrupt?}
    CheckPdb{--pdb enabled?}
    SuspendCapture[Suspend IO capturing]
    ShowCapture[Show captured output]
    EnterDebugger[Enter pdb post-mortem]
    Continue[Continue test execution]
    End[Test Run End]

    Start --> CheckTrace
    CheckTrace -- Yes --> WrapTest
    CheckTrace -- No --> RunTest
    WrapTest --> RunTest
    RunTest --> CheckError
    CheckError -- Yes --> CheckPdb
    CheckError -- No --> Continue
    CheckPdb -- Yes --> SuspendCapture
    CheckPdb -- No --> Continue
    SuspendCapture --> ShowCapture --> EnterDebugger --> Continue
    Continue --> End

Summary

The [debugging.py](/projects/286/67457) module is a core pytest plugin that enhances developer productivity by integrating Python's interactive debugger into test runs. It supports automatic post-failure debugging, immediate debugging on test start, and custom debugger classes while carefully managing pytest's output capturing system to maintain clear and interactive debugging sessions. The wrapping and extension of the pdb class ensure seamless cooperation between pytest's test lifecycle and the interactive debugging environment.

This module interacts closely with pytest’s core systems such as configuration, test reporting, capture management, and plugin architecture to provide an extensible, robust debugging experience tailored to automated testing workflows.