raises_group.py
Overview
The [raises_group.py](/projects/286/67439) file is a comprehensive test suite and utility module designed to extend and enhance the capabilities of Pytest’s exception assertion mechanisms, specifically for handling **exception groups** introduced in Python 3.11 (`ExceptionGroup` and `BaseExceptionGroup`). It builds upon Pytest's existing `RaisesExc` and `RaisesGroup` classes to support more complex scenarios involving nested exception groups, multiple expected exceptions, and flexible matching criteria.
This file primarily contains:
Helper functions for error message formatting and regex escaping.
Extensive test cases validating the behavior of
RaisesGroupandRaisesExcwhen dealing withExceptionGroupexceptions.Tests for features such as nested groups, flattening of subgroups, matching messages, custom checks, and unwrapped exceptions.
Error handling and user guidance for common pitfalls and edge cases.
Integration tests ensuring compatibility with Pytest’s
raisesandxfailmarkers.
The file serves both as documentation through tests and as a validation tool for the correctness and robustness of exception group handling in Pytest.
Key Classes and Functions
Imported Classes and Functions (from other modules)
RaisesExc: A Pytest context manager for asserting that a block of code raises an expected exception (or exceptions) optionally matching criteria like regex or a user-defined check.RaisesGroup: ExtendsRaisesExcto handle groups of exceptions (ExceptionGroup), matching multiple expected exceptions or nested groups.repr_callable: Utility to generate string representations of callables for error messages.pytest.raises: Pytest’s built-in context manager to check for exceptions.
These are imported and tested extensively in this file but are implemented elsewhere (likely in `pytest.raises` module).
Function: wrap_escape(s: str) -> str
**Purpose:** Wraps a string with `^` and `$` anchors and escapes all regex meta-characters in the string to create a regex that matches the exact input string.
**Parameters:**
s(str): The input string to be escaped and anchored.
**Returns:**
str: A regex string that matches the exact input strings.
**Usage Example:**
pattern = wrap_escape("foo.bar")
# pattern == "^foo\\.bar$"
Function: fails_raises_group(msg: str, add_prefix: bool = True) -> RaisesExc[Failed]
**Purpose:** Helper function to create a Pytest raises context expecting a failure (`Failed` exception) with a specific error message matching `msg`. It is used to test negative scenarios where `RaisesGroup` is expected to fail.
**Parameters:**
msg(str): The error message expected on failure; must not end with a newline.add_prefix(bool, defaultTrue): Whether to prepend the standard prefix"Raised exception group did not match: "to the message.
**Returns:**
RaisesExc[Failed]: A Pytest context manager expecting aFailedexception with a matching message.
**Usage Example:**
with fails_raises_group("some error message"):
# code that triggers a failure with 'some error message'
Testing RaisesGroup and Related Features
The majority of this file consists of **test functions** prefixed by `test_`, which validate the behavior and robustness of `RaisesGroup` and `RaisesExc` under various scenarios.
General Test Categories
Basic correctness and error handling (
test_raises_group,test_raisesexc)Handling multiple exceptions and ordering (
test_incorrect_number_exceptions,test_misordering_example)Nested exception groups and flattening (
test_flatten_subgroups,test_suggestion_on_nested_and_brief_error)Matching exception messages (
test_match,test_raisesexc_match)Custom check functions for exceptions (
test_check,test_RaisesExc_check)Handling unwrapped exceptions and allow_unwrapped flag (
test_catch_unwrapped_exceptions,test_unwrapped_match_check)Message formatting and assertion failure messages (
test_message,test_assert_message,test_assert_message_nested,test_message_indent)String representations (
__str__and__repr__) of RaisesGroup and RaisesExc (test_raisesexc_tostring,test_raisesgroup_tostring)Integration with Pytest features like
xfail(test_xfail_raisesgroup,test_xfail_RaisesExc)Parametrized tests and compatibility with Pytest's
raises(test_parametrizing_conditional_raisesgroup)Type annotations and generics restrictions (
test_annotated_group)Support for tuple exceptions in RaisesExc but not RaisesGroup (
test_tuples)Identity issues when multiple similar exceptions appear (
test_identity_oopsies)Coverage for edge cases and patched behaviors (
test_check_no_patched_repr, marked to skip with hypothesis present)
Example: test_raises_group
This test validates:
Errors raised for invalid
RaisesExcandRaisesGroupinstantiations.Matching of exception groups raised in various nested and multiple-exception scenarios.
Order independence of exceptions in groups.
Nested
RaisesGrouphandling including recursive groups.Failure cases and helpful error messages.
Important Implementation Details
Exception Group Handling:
The tests rely on Python 3.11’s nativeExceptionGroupandBaseExceptionGroupclasses or the backportedexceptiongroupmodule for earlier Python versions.Flattening Subgroups:
RaisesGroupsupports aflatten_subgroupsparameter to loosen matching semantics by flattening nested exception groups during matching.Allowing Unwrapped Exceptions:
Theallow_unwrappedflag allows matching of exceptions that are not wrapped in anExceptionGroup, for compatibility with legacy or simpler exception handling.Greedy Matching Algorithm:
The matching algorithm attempts a greedy approach to pair expected exceptions with raised exceptions; this can cause subtle failures requiring users to be more specific withRaisesExc.Custom Checks and Regex Matching:
Users can supply custom callable checks and regex patterns to match exception messages, but these are disabled withallow_unwrapped=Truefor unwrapped exceptions.Error Message Composition:
Detailed and nested error messages are generated to help users understand mismatches, including suggestions to useflatten_subgroups=Trueor to escape regex patterns.
Interaction with Other System Components
Pytest Core:
Extends Pytest's native exception handling, particularly integrating withpytest.raises,pytest.mark.xfail, and thepytest._code.ExceptionInfoAPI._pytest.raisesModule:
Extensively uses and tests classes from_pytest.raisessuch asRaisesExcandRaisesGroup.exceptiongroupBackport:
Supports older Python versions (<3.11) by importingExceptionGroupandBaseExceptionGroupfrom theexceptiongrouppackage.pytest.pytester:
Uses thePytesterutility to create integration tests that verify behavior of tests that useRaisesGroupandRaisesExc.
Visual Diagram
classDiagram
class RaisesGroup {
+__init__(*expected_exceptions, allow_unwrapped=False, flatten_subgroups=False, match=None, check=None)
+__enter__()
+__exit__(exc_type, exc_value, traceback)
+matches(exception) bool
+__repr__() str
+__str__() str
}
class RaisesExc {
+__init__(exception_type=None, match=None, check=None)
+__enter__()
+__exit__(exc_type, exc_value, traceback)
+matches(exception) bool
+__repr__() str
+__str__() str
}
class Pytester {
+makepyfile(source:str)
+runpytest()
+assert_outcomes(xfailed:int)
}
class ExceptionGroup {
+__init__(message:str, exceptions:tuple[BaseException])
+add_note(note:str)
}
RaisesGroup ..> RaisesExc : uses/contains
RaisesGroup --> ExceptionGroup : matches against
RaisesExc --> BaseException : matches against
test_xfail_raisesgroup ..> Pytester : uses
test_xfail_RaisesExc ..> Pytester : uses
Summary
The [raises_group.py](/projects/286/67439) file is a detailed and exhaustive test suite that verifies and documents the behavior of Pytest's enhanced exception assertion tools (`RaisesGroup` and `RaisesExc`) for handling Python 3.11 style exception groups. It ensures that users can write precise, flexible, and helpful tests involving complex nested exceptions with clear error reporting and useful suggestions for common issues.
This file is crucial for maintaining correctness and usability of Pytest’s exception group support, interfacing tightly with core Pytest components and Python’s exception group mechanism.
Usage Highlights
Use
RaisesGroupto expect multiple exceptions grouped together or nested exception groups.Use
RaisesExcfor matching individual exceptions with flexible criteria.Leverage
flatten_subgroups=Trueto loosen matching rules by flattening nested groups.Use
allow_unwrapped=Truecautiously to catch exceptions not wrapped in groups.Provide
matchpatterns orcheckfunctions for fine-grained control.Read detailed failure messages for guidance on fixing test mismatches.
If you are extending or debugging Pytest exception assertions, this file serves as an invaluable reference and validation tool.