Skip to content

Commit

Permalink
Fixed bare raise and exception chaining when a handler raises an ex…
Browse files Browse the repository at this point in the history
…ception
  • Loading branch information
agronholm committed Jul 16, 2023
1 parent 452ba09 commit 258eaad
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 2 deletions.
7 changes: 7 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@ Version history

This library adheres to `Semantic Versioning 2.0 <http://semver.org/>`_.

**UNRELEASED**

- Fixed plain ``raise`` statement in an exception handler callback to work like a
``raise`` in an ``except*`` block
- Fixed new exception group not being chained to the original exception when raising an
exception group from exceptions raised in handler callbacks

**1.1.2**

- Changed handling of exceptions in exception group handler callbacks to not wrap a
Expand Down
7 changes: 5 additions & 2 deletions src/exceptiongroup/_catch.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def __exit__(
elif unhandled is None:
return True
else:
raise unhandled from None
raise unhandled from exc

return False

Expand All @@ -49,7 +49,10 @@ def handle_exception(self, exc: BaseException) -> BaseException | None:
matched, excgroup = excgroup.split(exc_types)
if matched:
try:
handler(matched)
try:
raise matched
except BaseExceptionGroup:
handler(matched)
except BaseException as new_exc:
new_exceptions.append(new_exc)

Expand Down
15 changes: 15 additions & 0 deletions tests/test_catch.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,21 @@ def handler(exc):
raise ExceptionGroup("booboo", [ValueError("bar")])


def test_catch_handler_reraises():
def handler(exc):
raise

with pytest.raises(ExceptionGroup) as exc:
with catch({(ValueError,): handler, (RuntimeError,): lambda eg: None}):
original_exc = ExceptionGroup("booboo", [ValueError("bar"), RuntimeError()])
raise original_exc

assert len(exc.value.exceptions) == 1
assert isinstance(exc.value.exceptions[0], ValueError)
assert str(exc.value.exceptions[0]) == "bar"
assert exc.value.__cause__ is original_exc


def test_catch_subclass():
lookup_errors = []
with catch({LookupError: lookup_errors.append}):
Expand Down

0 comments on commit 258eaad

Please sign in to comment.