Skip to content

Commit

Permalink
Made catch() raise TypeError on async handler (#69)
Browse files Browse the repository at this point in the history
Co-authored-by: Alex Grönholm <alex.gronholm@nextday.fi>
  • Loading branch information
jakkdl and agronholm committed Jul 12, 2023
1 parent 84b4134 commit 1d604fb
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 1 deletion.
5 changes: 5 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ Version history

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

**UNRELEASED**
- `catch()` now raises a `TypeError` if passed an async exception handler instead of
just giving a `RuntimeWarning` about the coroutine never being awaited. (#66, PR by
John Litborn)

**1.1.2**

- Changed handling of exceptions in exception group handler callbacks to not wrap a
Expand Down
9 changes: 8 additions & 1 deletion src/exceptiongroup/_catch.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from __future__ import annotations

import inspect
import sys
from collections.abc import Callable, Iterable, Mapping
from contextlib import AbstractContextManager
Expand Down Expand Up @@ -49,9 +50,15 @@ def handle_exception(self, exc: BaseException) -> BaseException | None:
matched, excgroup = excgroup.split(exc_types)
if matched:
try:
handler(matched)
result = handler(matched)
except BaseException as new_exc:
new_exceptions.append(new_exc)
else:
if inspect.iscoroutine(result):
raise TypeError(
f"Error trying to handle {matched!r} with {handler!r}. "
"Exception handler must be a sync function."
) from exc

if not excgroup:
break
Expand Down
14 changes: 14 additions & 0 deletions tests/test_catch.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,3 +162,17 @@ def test_catch_subclass():
assert isinstance(lookup_errors[0], ExceptionGroup)
exceptions = lookup_errors[0].exceptions
assert isinstance(exceptions[0], KeyError)


def test_async_handler(request):
async def handler(eg):
pass

def delegate(eg):
coro = handler(eg)
request.addfinalizer(coro.close)
return coro

with pytest.raises(TypeError, match="Exception handler must be a sync function."):
with catch({TypeError: delegate}):
raise ExceptionGroup("message", TypeError("uh-oh"))

0 comments on commit 1d604fb

Please sign in to comment.