@@ -19,7 +19,8 @@ propose adding two new methods to exception objects:
1919
2020- :meth: `!BaseException.preserve_context `, a context manager which
2121 saves and restores the :attr: `!self.__context__ ` attribute of ``self ``,
22- so that raising the exception within an ``except: `` block.
22+ so that re-raising the exception within another handler does not overwrite
23+ the existing context.
2324
2425We expect this to enable more concise expression of error handling logic in
2526many medium-complexity cases. Without them, exception-group handlers will
@@ -127,8 +128,8 @@ Without ``.preserve_context()``, this could would have to either:
127128 making code difficult to follow in nontrivial cases, or
128129* discard the existing ``__context__ `` of the ``first `` exception, replacing
129130 it with an ``ExceptionGroup `` which is simply an implementation detail, or
130- * use ``try/except `` instead of ``except* ``, handling the possibility that
131- the group doesn't contain an ``HTTPException `` at all,[#catch-raw-group]_ or
131+ * use ``try/except `` instead of ``except* ``, handling the possibility that the
132+ group doesn't contain an ``HTTPException `` at all,\ [#catch-raw-group ]_ or
132133* implement the semantics of ``.preserve_context() `` inline::
133134
134135 prev_ctx = first.__context__
@@ -146,13 +147,13 @@ Backwards Compatibility
146147
147148Adding new methods to built-in classes, especially those as widely used as
148149``BaseException ``, can have substantial impacts. However, GitHub search shows
149- no collisions for these method names (`zero hits <flat-exceptions >`_ and
150- `three unrelated hits <preserve-context >`_ respectively). If user-defined
150+ no collisions for these method names (`zero hits <flat_exceptions >`_ and
151+ `three unrelated hits <preserve_context >`_ respectively). If user-defined
151152methods with these names exist in private code they will shadow those proposed
152153in the PEP, without changing runtime behavior.
153154
154- .. _ flat-exceptions : https://github.com/search?q=%2F%5C.flat_exceptions%5C%28%2F+language%3APython&type=code
155- .. _ preserve-context : https://github.com/search?q=%2F%5C.preserve_context%5C%28%2F+language%3APython&type=code
155+ .. _ flat_exceptions : https://github.com/search?q=%2F%5C.flat_exceptions%5C%28%2F+language%3APython&type=code
156+ .. _ preserve_context : https://github.com/search?q=%2F%5C.preserve_context%5C%28%2F+language%3APython&type=code
156157
157158
158159How to Teach This
@@ -165,13 +166,14 @@ In intermediate classes, we recommend teaching ``.flat_exceptions()`` together
165166with the ``.split() `` and ``.subgroup() `` methods, and mentioning
166167``.preserve_context() `` as an advanced option to address specific pain points.
167168
168- Both the API reference and the existing `ExceptionGroup tutorial
169- <https://docs.python.org/3/tutorial/errors.html#exception-groups> `_ should
170- be updated to demonstrate and explain the new methods. The tutorial should
171- include examples of common patterns where ``.flat_exceptions() `` and
169+ Both the API reference and the existing `ExceptionGroup tutorial <tutorial >`_
170+ should be updated to demonstrate and explain the new methods. The tutorial
171+ should include examples of common patterns where ``.flat_exceptions() `` and
172172``.preserve_context() `` help simplify error handling logic. Downstream
173173libraries which often use exception groups could include similar docs.
174174
175+ .. _tutorial : https://docs.python.org/3/tutorial/errors.html#raising-and-handling-multiple-unrelated-exceptions
176+
175177We have also designed lint rules for inclusion in ``flake8-async `` which will
176178suggest using ``.flat_exceptions() `` when iterating over ``group.exceptions ``
177179or re-raising a leaf exception, and suggest using ``.preserve_context() `` when
@@ -288,7 +290,6 @@ Add utility functions instead of methods
288290
289291Rather than adding methods to exceptions, we could provide utility functions
290292like the reference implementations above.
291-
292293There are however several reasons to prefer methods: there's no obvious place
293294where helper functions should live, they take exactly one argument which must
294295be an instance of ``BaseException ``, and methods are both more convenient and
@@ -369,15 +370,15 @@ Footnotes
369370 `six <https://github.com/PaLora16/ExceptionsGroupsValidators/blob/41152a86eec695168fdec74653694658ddc788fc/main.py#L39-L44 >`__,
370371 `seven <https://github.com/reactive-python/reactpy/blob/178fc05de7756f7402ed2ee1e990af0bdad42d9e/src/reactpy/backend/starlette.py#L164-L170 >`__)
371372
372- indicating that more than a quarter of _all_ hits for this fairly general
373+ indicating that more than a quarter of * all * hits for this fairly general
373374 search would benefit from the methods proposed in this PEP.
374375
375376 .. [#catch-raw-group ]
376377 This remains very rare, and most cases duplicate logic across
377378 ``except FooError: `` and ``except ExceptionGroup: # containing FooError ``
378- clauses rather than using something like the as_group trick.
379- We expect that ``except* `` will be widely used in such cases, before
380- the methods proposed by this PEP are widely available.
379+ clauses rather than using something like the `` as_group() `` trick.
380+ We expect that ``except* `` will be widely used in such cases by the time
381+ that the methods proposed by this PEP are widely available.
381382
382383
383384 Copyright
0 commit comments