Skip to content

fix: RaisesGroup check() no longer called with sub-exceptions (#14324) - #15116

Open
DawnofGenX wants to merge 3 commits into
pytest-dev:mainfrom
DawnofGenX:fix-raisesgroup-check-14324
Open

DawnofGenX wants to merge 3 commits into
pytest-dev:mainfrom
DawnofGenX:fix-raisesgroup-check-14324

Conversation

@DawnofGenX

Copy link
Copy Markdown

Summary

Fixes #14324.

RaisesGroup's check callback was being called a second time with a contained sub-exception after the callback had already rejected the group. This came from a speculative probe used to build a nicer failure hint ("did return True for the expected ... You might want RaisesGroup(RaisesExc(..., check=<...>))"). It:

  • violated the documented contract that check receives the exception group itself,
  • crashed callbacks that assume they are always handed a group (e.g. touching e.exceptions raised AttributeError on the sub-exception and leaked out of pytest.raises matching), and
  • caused surprising double-calls for stateful callbacks.

Fix

The speculative sub-exception probe is removed entirely — not merely wrapped in try/except. When check rejects the group, the failure reason is now set directly and check is never invoked again. This drops the "You might want RaisesGroup(RaisesExc(...))" hint, but restores the contract and eliminates the whole crash class.

Changes

  • src/_pytest/raises.py — remove the sub-exception probe in RaisesGroup check handling.
  • testing/python/raises_group.py — regression test asserting check is only ever called with the group and never crashes when it uses group-only attributes.
  • changelog/14324.bugfix.rst — changelog entry.

Test plan

  • New regression test test_check_not_called_with_subexception_issue_14324 fails on main (verified red: AttributeError: 'ValueError' object has no attribute 'exceptions') and passes with the fix.
  • testing/python/raises_group.py + testing/python/raises.py pass in full (67 passed).
  • CI green.

Closes #14324

…est-dev#14324)

Reproduces the bug where RaisesGroup.matches calls the user's check()
function a second time with a contained exception (not the group) when
the group check returns False, crashing with AttributeError for checks
that assume an ExceptionGroup. TDD red phase; no fix included.
…#14324)

When the group-level check returned False, matches() re-invoked the
user's check() with a contained exception to build a "did return True
for the expected X" suggestion. This crashed checks that assume an
ExceptionGroup (AttributeError) and violated the documented contract
that check receives the group.

The check callback is now only ever called with the group itself; the
speculative sub-exception probe is removed, so the suggestion text is
dropped from the failure message.
@psf-chronographer psf-chronographer Bot added the bot:chronographer:provided (automation) changelog entry is part of PR label Sep 30, 2026
mypy reports the comment as unused; the error it suppressed no longer
exists. pre-commit.ci flagged this on pytest-dev#15116.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bot:chronographer:provided (automation) changelog entry is part of PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

pytest.RaisesGroup calls the check function with simple exceptions instead of the group

1 participant