@@ -19,7 +19,8 @@ propose adding two new methods to exception objects:
19
19
20
20
- :meth: `!BaseException.preserve_context `, a context manager which
21
21
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.
23
24
24
25
We expect this to enable more concise expression of error handling logic in
25
26
many medium-complexity cases. Without them, exception-group handlers will
@@ -121,38 +122,30 @@ Usage example:
121
122
with first.preserve_context():
122
123
raise first
123
124
124
- Without ``.preserve_context() ``, this could would have to either:
125
+ Without ``.preserve_context() ``, this code would have to either:
125
126
126
127
* arrange for the exception to be raised *after * the ``except* `` block,
127
128
making code difficult to follow in nontrivial cases, or
128
129
* discard the existing ``__context__ `` of the ``first `` exception, replacing
129
130
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
132
- * implement the semantics of ``.preserve_context() `` inline::
133
-
134
- prev_ctx = first.__context__
135
- try:
136
- raise first # or `raise first from None`, etc.
137
- finally:
138
- first.__context__ = prev_ctx
139
- del prev_ctx # break gc cycle
140
-
141
- which is not *literally unheard-of*, but remains very very rare.
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
133
+ * implement the semantics of ``.preserve_context() `` inline; while this is not
134
+ *literally unheard-of *, it remains very rare.
142
135
143
136
144
137
Backwards Compatibility
145
138
=======================
146
139
147
140
Adding new methods to built-in classes, especially those as widely used as
148
141
``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
151
- methods with these names exist in private code they will shadow those proposed
152
- in the PEP, without changing runtime behavior.
142
+ no collisions for these method names (`zero hits `__ and
143
+ `three unrelated hits `__ respectively). If user-defined methods with these
144
+ names exist in private code they will shadow those proposed in the PEP,
145
+ without changing runtime behavior.
153
146
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
147
+ __ https://github.com/search?q=%2F%5C.flat_exceptions%5C%28%2F+language%3APython&type=code
148
+ __ https://github.com/search?q=%2F%5C.preserve_context%5C%28%2F+language%3APython&type=code
156
149
157
150
158
151
How to Teach This
@@ -165,13 +158,14 @@ In intermediate classes, we recommend teaching ``.flat_exceptions()`` together
165
158
with the ``.split() `` and ``.subgroup() `` methods, and mentioning
166
159
``.preserve_context() `` as an advanced option to address specific pain points.
167
160
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
161
+ Both the API reference and the existing `ExceptionGroup tutorial `__
162
+ should be updated to demonstrate and explain the new methods. The tutorial
163
+ should include examples of common patterns where ``.flat_exceptions() `` and
172
164
``.preserve_context() `` help simplify error handling logic. Downstream
173
165
libraries which often use exception groups could include similar docs.
174
166
167
+ __ https://docs.python.org/3/tutorial/errors.html#raising-and-handling-multiple-unrelated-exceptions
168
+
175
169
We have also designed lint rules for inclusion in ``flake8-async `` which will
176
170
suggest using ``.flat_exceptions() `` when iterating over ``group.exceptions ``
177
171
or re-raising a leaf exception, and suggest using ``.preserve_context() `` when
@@ -288,7 +282,6 @@ Add utility functions instead of methods
288
282
289
283
Rather than adding methods to exceptions, we could provide utility functions
290
284
like the reference implementations above.
291
-
292
285
There are however several reasons to prefer methods: there's no obvious place
293
286
where helper functions should live, they take exactly one argument which must
294
287
be an instance of ``BaseException ``, and methods are both more convenient and
@@ -369,15 +362,15 @@ Footnotes
369
362
`six <https://github.com/PaLora16/ExceptionsGroupsValidators/blob/41152a86eec695168fdec74653694658ddc788fc/main.py#L39-L44 >`__,
370
363
`seven <https://github.com/reactive-python/reactpy/blob/178fc05de7756f7402ed2ee1e990af0bdad42d9e/src/reactpy/backend/starlette.py#L164-L170 >`__)
371
364
372
- indicating that more than a quarter of _all_ hits for this fairly general
365
+ indicating that more than a quarter of * all * hits for this fairly general
373
366
search would benefit from the methods proposed in this PEP.
374
367
375
368
.. [#catch-raw-group ]
376
369
This remains very rare, and most cases duplicate logic across
377
370
``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.
371
+ clauses rather than using something like the `` as_group() `` trick.
372
+ We expect that ``except* `` will be widely used in such cases by the time
373
+ that the methods proposed by this PEP are widely available.
381
374
382
375
383
376
Copyright
0 commit comments