test_recwarn.py
Overview
`test_recwarn.py` is a comprehensive test suite designed to validate the warning capturing and handling capabilities within the `pytest` testing framework. This file specifically tests the `pytest.warns`, `pytest.deprecated_call`, and `WarningsRecorder` utilities, which facilitate the detection, inspection, and assertion of Python warnings (including subclasses and deprecation warnings) during test execution.
The tests cover scenarios such as:
Basic warning capture and inspection.
Subclass hierarchy handling in warnings.
Deprecated call detection and validation.
Correct behavior of warning context managers.
Interaction of warnings with test control flow (skips, failures, interrupts).
Validation of warning message types.
Edge cases like multiple warnings, matching regexes, and re-emission behavior.
This file ensures that pytest’s warning-related helpers behave correctly, improving test reliability and developer feedback when warnings occur.
Detailed Explanations
Imports and Setup
warnings: Python's built-in warnings module.pytest: Testing framework used for assertions, decorators, and exception handling.Pytester,WarningsRecorder,ExitCode: pytest internal utilities and classes used for testing warnings and test runs.
Functions
test_recwarn_stacklevel(recwarn: WarningsRecorder) -> None
Purpose: Test that the warning recorded by
recwarnhas the correct filename attribute (the current file).Parameters:
recwarn— aWarningsRecorderpytest fixture capturing warnings issued in the test.Behavior: Issues a warning and asserts the captured warning's filename matches the current file.
Usage:
def test_example(recwarn): warnings.warn("example warning") warn = recwarn.pop() assert warn.filename == __file__
test_recwarn_functional(pytester: Pytester) -> None
Purpose: Functional test that a warning is captured correctly in a dynamically created test file.
Parameters:
pytester— pytest fixture to run tests programmatically.Behavior: Creates a test file that issues a warning; runs it and asserts it passes.
Usage: Used internally to verify pytest's warning capture in real test runs.
test_recwarn_captures_deprecation_warning(recwarn: WarningsRecorder) -> None
Purpose: Verify that
recwarncapturesDeprecationWarningby default without custom filter settings.Behavior: Issues a
DeprecationWarningand asserts that it is captured.
Class: TestSubclassWarningPop
Tests how warnings behave with subclass hierarchies when using `pop()` on recorded warnings.
Inner Classes:
ParentWarning(Warning)ChildWarning(ParentWarning)ChildOfChildWarning(ChildWarning)
Static Method:
raise_warnings_from_list(_warnings: list[type[Warning]]): issues warnings for each warning type in list.
Test Methods:
test_pop_finds_exact_match(): Verifiespop()finds exact warning type matches.test_pop_raises_if_no_match(): Checkspop()raises if no matching warning is found.test_pop_finds_best_inexact_match(): Checkspop()finds the best matching subclass warning when exact is not found.
Class: TestWarningsRecorderChecker
Tests internal workings of `WarningsRecorder` and related behavior.
test_recording(): Basic recording, popping, clearing, and error-raising behavior.test_warn_stacklevel(): Tests warnings with explicit stack levels.test_typechecking(): Validates type checking forWarningsChecker.test_invalid_enter_exit(): Asserts correct exceptions when entering or exitingWarningsRecordercontext improperly.
Class: TestDeprecatedCall
Tests the `pytest.deprecated_call()` helper that asserts a deprecation warning is raised during a function call or code block.
Methods like
depanddep_explicitsimulate deprecated functions emitting warnings.Tests cover:
Raising exceptions when no deprecation warning occurs.
Return value preservation.
Context manager and function call modes.
Matching warnings with regex.
Behavior with multiple warning types.
Ensuring
deprecated_calldoes not interfere with global warning state.
Uses pytest parametrization extensively to cover various warning subclasses and call modes.
Class: TestWarns
Extensive tests for `pytest.warns()`, which asserts that a piece of code emits specified warnings.
Tests include:
Validation of callable parameters.
Handling multiple messages and different warning types.
Using
pytest.warns()as a context manager.Recording emitted warnings.
Matching warnings by subclass and regex.
Behavior with multiple nested
warnscontexts.Interaction with pytest control flows like
skip(),fail(),exit(), and exceptions.Handling of invalid warning messages that are neither strings nor
Warninginstances.Testing re-emission and suppression of warnings.
Ensuring warnings are captured even if already triggered before.
Standalone Functions for Edge Cases
test_raise_type_error_on_invalid_warning(): Checks that warnings with invalid message types raiseTypeError.test_no_raise_type_error_on_valid_warning(): Parametrized test checking valid warning messages (strings and warning instances) do not raise errors.test_raise_type_error_on_invalid_warning_message_cpython(): Skipped on PyPy, tests CPython-specific warning behavior with invalid message.test_multiple_arg_custom_warning(): Tests custom warning classes with multiple constructor arguments.
Important Implementation Details and Algorithms
The tests heavily leverage pytest fixtures (
recwarn,pytester) to capture and manipulate warning records.Warning capturing uses context managers (
with pytest.warns():) and function decorators.Matching warnings by types and regex is tested for robustness, including subclass matching and best-fit matches.
Tests ensure no side effects or global state pollution occurs during warning capturing (
onceregistry,filterspreservation).The test suite handles complex scenarios like nested warning contexts and interleaved warning and exception raising.
Parametrization is used to reduce code duplication and increase coverage for multiple warning types and usage modes.
Interaction with Other Parts of the System
This file tests core pytest warning utilities, which interact with:
The Python
warningsmodule for emitting and filtering warnings.Pytest's internal
WarningsRecorderandWarningsCheckerclasses for capturing warnings during test execution.Pytest's test runner (via
Pytester) to execute generated test files and check outcomes.pytest's failure and skip mechanisms to confirm correct behavior when warnings interact with test control flow.
By verifying these interactions, this file helps ensure reliable and consistent warning handling across the pytest ecosystem.
Visual Diagram
classDiagram
class TestSubclassWarningPop {
+raise_warnings_from_list(_warnings: list[type[Warning]])
+test_pop_finds_exact_match()
+test_pop_raises_if_no_match()
+test_pop_finds_best_inexact_match()
}
class TestWarningsRecorderChecker {
+test_recording()
+test_warn_stacklevel()
+test_typechecking()
+test_invalid_enter_exit()
}
class TestDeprecatedCall {
+dep(i: int, j: int | None = None) -> int
+dep_explicit(i: int) -> None
+test_deprecated_call_raises()
+test_deprecated_call()
+test_deprecated_call_ret()
+test_deprecated_call_preserves()
+test_deprecated_explicit_call_raises()
+test_deprecated_explicit_call()
+test_deprecated_call_no_warning(mode)
+test_deprecated_call_modes(warning_type, mode, call_f_first)
+test_deprecated_call_specificity()
+test_deprecated_call_supports_match()
}
class TestWarns {
+test_check_callable()
+test_several_messages()
+test_function()
+test_warning_tuple()
+test_as_contextmanager()
+test_record()
+test_record_only()
+test_record_only_none_type_error()
+test_record_by_subclass()
+test_double_test(pytester: Pytester)
+test_match_regex()
+test_one_from_multiple_warns()
+test_none_of_multiple_warns()
+test_can_capture_previously_warned()
+test_warns_context_manager_with_kwargs()
+test_re_emit_single()
+test_re_emit_multiple()
+test_re_emit_match_single()
+test_re_emit_match_multiple()
+test_re_emit_non_match_single()
+test_catch_warning_within_raise()
+test_skip_within_warns(pytester: Pytester)
+test_fail_within_warns(pytester: Pytester)
+test_exit_within_warns(pytester: Pytester)
+test_keyboard_interrupt_within_warns(pytester: Pytester)
}
TestSubclassWarningPop --> Warning
TestWarningsRecorderChecker --> WarningsRecorder
TestDeprecatedCall --> pytest.deprecated_call
TestWarns --> pytest.warns
Summary
`test_recwarn.py` is a critical test module that validates pytest's handling of Python warnings. It ensures that warnings are captured, matched, and asserted correctly in various complex scenarios, including subclass hierarchies, deprecation calls, and warning context managers. The file also tests the robustness of warning-related APIs regarding error conditions, message validation, and interaction with pytest's control flow mechanisms.
This test suite guarantees that pytest provides reliable and predictable warning assertion tools, which are essential for maintaining high-quality, warning-aware test suites in Python projects.