Warning Filters and Reporting
Purpose
This component addresses the need to manage Python warnings systematically during the entire pytest test lifecycle. It provides integration with pytest’s hook system to apply warning filters and capture warnings at key phases such as configuration, test collection, and test execution. The goal is to ensure that warnings are consistently filtered, recorded, and reported, improving test reliability and user awareness of potential issues in tested code or pytest itself.
Unlike generic warning capture, this subtopic focuses on dynamically applying filters from multiple sources—including configuration files, command-line options, and test-specific markers—and emitting captured warnings through pytest’s event system for further handling or reporting.
Functionality
The core functionality revolves around a context manager that wraps major pytest phases to catch and process warnings:
Dynamic Application of Filters: Filters are applied from several places:
filterwarningsentries from pytest ini configuration.Command-line -W or --pythonwarnings options.
@pytest.mark.filterwarnings markers attached to individual tests.
Warning Capture and Hook Emission: Inside the context, Python’s warnings.catch_warnings(record=True) is used to capture emitted warnings. Each captured warning triggers a pytest hook call
pytest_warning_recordedwith metadata about the warning, such as when it occurred and the test item involved.Phase Coverage: The context manager is applied via hook wrappers around critical pytest lifecycle hooks:
pytest_load_initial_conftests and pytest_configure for configuration phase warnings.
pytest_collection for warnings during test discovery.
pytest_runtest_protocolfor warnings during individual test execution.pytest_terminal_summary and pytest_sessionfinish to catch any late warnings.
Default Filter Behavior: If no user filters are set, deprecation warnings are enabled by default to ensure users are informed about deprecated code usage without explicit configuration.
Marker-Based Filtering: Tests can individually declare warning filters via @pytest.mark.filterwarnings, allowing fine-grained control over warnings expected or ignored in specific tests.
Non-Recording Context: During some late phases (like final config cleanup), warnings are filtered but not recorded to avoid issues with reporting after terminal output has completed.
Example: Applying Markers and Filters
@ pytest.mark.filterwarnings("ignore::DeprecationWarning")
def test_example():
...
This marker adds a filter to ignore all deprecation warnings during that test’s execution.
Snippet Showing Hook Wrapping
@pytest.hookimpl(wrapper=True, tryfirst=True)
def pytest_runtest_protocol(item: Item) -> Generator[None, object, object]:
with catch_warnings_for_item(
config=item.config, ihook=item.ihook, when="runtest", item=item
):
return (yield)
Here the test run phase is wrapped with the warning-catching context manager, ensuring any warnings emitted during the test are captured and reported.
Integration
This subtopic tightly integrates with the parent topic (Warnings and Unraisable Exception Handling) by providing the mechanism to filter and report warnings, complementing other subtopics that capture warnings (`Warning Capture and Assertion`) and handle unraisable exceptions (`Unraisable Exception Management`).
It hooks into pytest’s lifecycle at multiple points, coordinating with the test collection and execution subsystems to ensure warnings are caught in all phases.
Works alongside pytest’s configuration system to read user-defined filters.
Emits captured warnings through pytest’s hook system (
pytest_warning_recorded), enabling plugins and reporters to react accordingly.Supports markers as a bridge between test code and the warning filter system, allowing test authors to customize warning behavior locally.
Complements the output capture system by ensuring warnings are processed separately and not lost amidst stdout/stderr capturing.
Overall, it acts as the central manager of warning filters and reporting policies, ensuring warnings are handled consistently across the entire pytest run.
Diagram: Warning Filter Application and Reporting Flow
flowchart TD
A[Start pytest Phase]
B[Enter catch_warnings_for_item Context]
C[Apply Config Filters]
D[Apply Cmdline Filters]
E[Apply Marker Filters (if test item)]
F[Execute Phase Code]
G[Capture Warnings Raised]
H[For Each Warning]
I[Call pytest_warning_recorded Hook]
J[Exit Context]
K[Continue pytest Phase]
A --> B
B --> C
C --> D
D --> E
E --> F
F --> G
G --> H
H --> I
I --> H
H --> J
J --> K
This flowchart illustrates how warning filters are applied from various sources before executing pytest phases, how warnings are captured within that context, and how each warning triggers a hook call for further processing.
This subtopic ensures that warnings are managed with precision and flexibility, enhancing pytest's robustness in alerting users to potential issues without being overwhelmed by noise.