Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
This repository was archived by the owner on Apr 10, 2022. It is now read-only.

Commit 46a0584

Browse filesBrowse files
authored
fleshed out use cases (#17)
* fleshed out use cases * Update except_star.md * added mention of asyncio.gather()
1 parent 34ffa5d commit 46a0584
Copy full SHA for 46a0584

File tree

1 file changed

+56
-13
lines changed
Filter options

1 file changed

+56
-13
lines changed

‎except_star.md

Copy file name to clipboardExpand all lines: except_star.md
+56-13Lines changed: 56 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,63 @@ group of unrelated exceptions being propagated together.
1414
## Motivation
1515

1616
The interpreter is currently able to propagate at most one exception at a
17-
time. The chaining features introduced in PEP3134 [reference] link together
18-
exceptions that are related to each other as the cause or context, but there
19-
are situations where there are multiple unrelated exceptions that need to be
20-
propagated together as the stack unwinds. Several real world use cases are
21-
listed below.
17+
time. The chaining features introduced in
18+
[PEP 3134](https://www.python.org/dev/peps/pep-3134/) link together exceptions that are
19+
related to each other as the cause or context, but there are situations where
20+
multiple unrelated exceptions need to be propagated together as the stack
21+
unwinds. Several real world use cases are listed below.
22+
23+
* **Concurrent errors**. Libraries for async concurrency provide APIs to invoke
24+
multiple tasks and return their results in aggregate. There isn't currently
25+
a good way for such libraries to handle situations where multiple tasks
26+
raise exceptions. The Python standard library's
27+
[`asyncio.gather()`](https://docs.python.org/3/library/asyncio-task.html#asyncio.gather)
28+
function provides two options: raise the first exception, or return the
29+
exceptions in the results list. The [Trio](https://trio.readthedocs.io/en/stable/)
30+
library has a `MultiError` exception type which it raises to report a
31+
collection of errors. Work on this PEP was initially motivated by the
32+
difficulties in handling `MultiError`s, which are detailed in a design
33+
document for an
34+
[improved version, `MultiError2`]([https://github.com/python-trio/trio/issues/611).
35+
That document demonstrates how difficult it is to create an effective API
36+
for reporting and handling multiple errors without the language changes we
37+
are proposing.
38+
39+
* **Multiple failures when retrying an operation.** The Python standard library's
40+
`socket.create_connection` may attempt to connect to different addresses,
41+
and if all attempts fail it needs to report that to the user. It is an open
42+
issue how to aggregate these errors, particularly when they are different
43+
[[Python issue 29980](https://bugs.python.org/issue29980)].
44+
45+
* **Multiple user callbacks fail.** The pytest library allows users to register
46+
finalizers which are executed at teardown. If more than one of these
47+
finalizers raises an exception, only the first is reported to the user. This
48+
can be improved with `ExceptionGroup`s, as explained in this issue by pytest
49+
developer Ran Benita [[Pytest issue 8217](https://github.com/pytest-dev/pytest/issues/8217)]
50+
51+
* **Multiple errors in a complex calculation.** The Hypothesis library performs
52+
automatic bug reduction (simplifying code that demonstrates a bug). In the
53+
process it may find variations that generate different errors, and
54+
(optionally) reports all of them
55+
[[Hypothesis documentation](https://hypothesis.readthedocs.io/en/latest/settings.html#hypothesis.settings.report_multiple_bugs)].
56+
An `ExceptionGroup` mechanism as we are proposing here can resolve some of
57+
the difficulties with debugging that are mentioned in the link above, and
58+
which are due to the loss of context/cause information (communicated
59+
by Hypothesis Core Developer Zac Hatfield-Dodds).
60+
61+
* **Errors in wrapper code.** The Python standard library's
62+
`tempfile.TemporaryDirectory` context manager
63+
had an issue where an exception raised during cleanup in `__exit__`
64+
effectively masked an exception that the user's code raised inside the context
65+
manager scope. While the user's exception was chained as the context of the
66+
cleanup error, it was not caught by the user's except clause
67+
[[Python issue 40857](https://bugs.python.org/issue40857)].
68+
The issue was resolved by making the cleanup code ignore errors, thus
69+
sidestepping the multiple exception problem. With the features we propose
70+
here, it would be possible for `__exit__` to raise an `ExceptionGroup`
71+
containing its own errors as well as the user's errors as unrelated errors,
72+
and this would allow the user to catch their own exceptions by their types.
2273

23-
[TODO: flesh these out]
24-
* asyncio programs, trio, etc
25-
26-
* Multiple errors from separate retries of an operation [https://bugs.python.org/issue29980]
27-
28-
* Situations where multiple unrelated exceptions may be of interest to calling code [https://bugs.python.org/issue40857]
29-
30-
* Multiple teardowns in pytest raising exceptions [https://github.com/pytest-dev/pytest/issues/8217]
3174

3275
## Rationale
3376

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.