Skip to content

Match only_rerun against wrapped exception causes - #364

Merged
icemac merged 5 commits into
pytest-dev:masterfrom
teddytennant:fix/pytest-rerunfailures
Sep 11, 2026
Merged

Match only_rerun against wrapped exception causes#364
icemac merged 5 commits into
pytest-dev:masterfrom
teddytennant:fix/pytest-rerunfailures

Conversation

@teddytennant

Copy link
Copy Markdown
Contributor

Fixes #353.

--only-rerun / only_rerun (and --rerun-except) match the outermost exception only. A transient error wrapped with raise ... from is not retried, even when the inner type is exactly what the filter is for.

def test_wrapped():
    try:
        raise MemoryError("out of memory")
    except MemoryError as error:
        raise RuntimeError("something failed") from error
$ pytest test_wrapped.py --reruns 2 --only-rerun MemoryError
1 failed            # not rerun

The same test without the wrapper reruns as expected. _try_match_error built the match string from excinfo.type / excinfo.value and never walked __cause__ or __context__.

The matcher now walks that chain (skipping a context suppressed by raise ... from None) and treats a hit on any linked exception as a match. Existing outer-exception matches are unchanged.

Regression tests cover a __cause__ wrap, an implicit __context__ wrap, the exception-class form of only_rerun, rerun_except on a wrapped error, a suppressed context, and a non-matching control.

$ pytest tests/test_pytest_rerunfailures.py -k wrapped
7 passed
$ pytest tests/
201 passed, 7 skipped

teddytennant and others added 3 commits September 6, 2026 15:48
Wrapped errors such as raise RuntimeError(...) from MemoryError(...)
were matched on the outer type and message only, so --only-rerun
MemoryError did not retry them.

@icemac icemac left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated review of this PR. Four findings; the first two are behavioral regressions I reproduced against master.

The root cause of both is that _try_match_error is shared by _matches_any_only_rerun_error and _matches_any_rerun_except_error, so walking the exception chain broadens both filters — and for --rerun-except, broader means fewer reruns.

Comment created by Claude

Comment thread src/pytest_rerunfailures.py Outdated
Comment thread src/pytest_rerunfailures.py
Comment thread src/pytest_rerunfailures.py
Comment thread README.rst
--rerun-except matching implicit __context__ skipped reruns for
exceptions raised inside except/finally. only_rerun still walks
the full chain.

@icemac icemac left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thank you for the PR.

@icemac
icemac enabled auto-merge (squash) September 11, 2026 06:24
@icemac
icemac merged commit 4220386 into pytest-dev:master Sep 11, 2026
45 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

only_rerun does not match exceptions wrapped by another exception (__cause__ / __context__ not inspected)

2 participants