pep 654: Fix indentation to use consistent 4 spaces in all snippets (#1833)
This commit is contained in:
parent
aebbd8c4fc
commit
3daf8f2199
266
pep-0654.rst
266
pep-0654.rst
|
@ -145,13 +145,20 @@ contains only those exceptions for which the condition is true:
|
|||
|
||||
.. code-block::
|
||||
|
||||
>>> eg = ExceptionGroup("one",
|
||||
... [TypeError(1),
|
||||
... ExceptionGroup("two",
|
||||
... [TypeError(2), ValueError(3)]),
|
||||
... ExceptionGroup("three",
|
||||
... [OSError(4)])
|
||||
... ])
|
||||
>>> eg = ExceptionGroup(
|
||||
... "one",
|
||||
... [
|
||||
... TypeError(1),
|
||||
... ExceptionGroup(
|
||||
... "two",
|
||||
... [TypeError(2), ValueError(3)]
|
||||
... ),
|
||||
... ExceptionGroup(
|
||||
... "three",
|
||||
... [OSError(4)]
|
||||
... )
|
||||
... ]
|
||||
... )
|
||||
>>> traceback.print_exception(eg)
|
||||
ExceptionGroup: one
|
||||
------------------------------------------------------------
|
||||
|
@ -307,13 +314,13 @@ exceptions can be handled by each ``except*`` clause:
|
|||
.. code-block::
|
||||
|
||||
try:
|
||||
...
|
||||
...
|
||||
except *SpamError:
|
||||
...
|
||||
...
|
||||
except *FooError as e:
|
||||
...
|
||||
...
|
||||
except *(BarError, BazError) as e:
|
||||
...
|
||||
...
|
||||
|
||||
In a traditional ``try-except`` statement there is only one exception to handle,
|
||||
so the body of at most one ``except`` clause executes; the first one that matches
|
||||
|
@ -346,10 +353,10 @@ Exceptions are matched using a subclass check. For example:
|
|||
.. code-block::
|
||||
|
||||
try:
|
||||
low_level_os_operation()
|
||||
low_level_os_operation()
|
||||
except *OSerror as eg:
|
||||
for e in eg.errors:
|
||||
print(type(e).__name__)
|
||||
for e in eg.errors:
|
||||
print(type(e).__name__)
|
||||
|
||||
could output:
|
||||
|
||||
|
@ -367,11 +374,11 @@ The order of ``except*`` clauses is significant just like with the regular
|
|||
.. code-block::
|
||||
|
||||
>>> try:
|
||||
... raise ExceptionGroup("problem", [BlockingIOError()])
|
||||
... raise ExceptionGroup("problem", [BlockingIOError()])
|
||||
... except *OSError as e: # Would catch the error
|
||||
... print(repr(e))
|
||||
... print(repr(e))
|
||||
... except *BlockingIOError: # Would never run
|
||||
... print('never')
|
||||
... print('never')
|
||||
...
|
||||
ExceptionGroup('problem', [BlockingIOError()])
|
||||
|
||||
|
@ -384,17 +391,20 @@ recursively, using the ``ExceptionGroup.split()`` method:
|
|||
.. code-block::
|
||||
|
||||
>>> try:
|
||||
... raise ExceptionGroup(
|
||||
... "eg",
|
||||
... [ValueError('a'),
|
||||
... TypeError('b'),
|
||||
... ExceptionGroup("nested", [TypeError('c'), KeyError('d')])
|
||||
... ]
|
||||
... )
|
||||
... raise ExceptionGroup(
|
||||
... "eg",
|
||||
... [
|
||||
... ValueError('a'),
|
||||
... TypeError('b'),
|
||||
... ExceptionGroup(
|
||||
... "nested",
|
||||
... [TypeError('c'), KeyError('d')])
|
||||
... ]
|
||||
... )
|
||||
... except *TypeError as e1:
|
||||
... print(f'e1 = {e1!r}')
|
||||
... print(f'e1 = {e1!r}')
|
||||
... except *Exception as e2:
|
||||
... print(f'e2 = {e2!r}')
|
||||
... print(f'e2 = {e2!r}')
|
||||
...
|
||||
e1 = ExceptionGroup('eg', [TypeError('b'), ExceptionGroup('nested', [TypeError('c')])])
|
||||
e2 = ExceptionGroup('eg', [ValueError('a'), ExceptionGroup('nested', [KeyError('d')])])
|
||||
|
@ -409,16 +419,19 @@ clauses, the remaining part of the ``ExceptionGroup`` is propagated on:
|
|||
.. code-block::
|
||||
|
||||
>>> try:
|
||||
... try:
|
||||
... raise ExceptionGroup(
|
||||
... "msg", [ValueError('a'), TypeError('b'), TypeError('c'), KeyError('e')]
|
||||
... )
|
||||
... except *ValueError as e:
|
||||
... print(f'got some ValueErrors: {e!r}')
|
||||
... except *TypeError as e:
|
||||
... print(f'got some TypeErrors: {e!r}')
|
||||
... try:
|
||||
... raise ExceptionGroup(
|
||||
... "msg", [
|
||||
... ValueError('a'), TypeError('b'),
|
||||
... TypeError('c'), KeyError('e')
|
||||
... ]
|
||||
... )
|
||||
... except *ValueError as e:
|
||||
... print(f'got some ValueErrors: {e!r}')
|
||||
... except *TypeError as e:
|
||||
... print(f'got some TypeErrors: {e!r}')
|
||||
... except ExceptionGroup as e:
|
||||
... print(f'propagated: {e!r}')
|
||||
... print(f'propagated: {e!r}')
|
||||
...
|
||||
got some ValueErrors: ExceptionGroup('msg', [ValueError('a')])
|
||||
got some TypeErrors: ExceptionGroup('msg', [TypeError('b'), TypeError('c')])
|
||||
|
@ -437,9 +450,9 @@ string. This is to make the type of ``e`` consistent and statically known:
|
|||
.. code-block::
|
||||
|
||||
>>> try:
|
||||
... raise BlockingIOError
|
||||
... raise BlockingIOError
|
||||
... except *OSError as e:
|
||||
... print(repr(e))
|
||||
... print(repr(e))
|
||||
...
|
||||
ExceptionGroup('', [BlockingIOError()])
|
||||
|
||||
|
@ -449,12 +462,12 @@ naked form:
|
|||
.. code-block::
|
||||
|
||||
>>> try:
|
||||
... try:
|
||||
... raise ValueError(12)
|
||||
... except *TypeError as e:
|
||||
... print('never')
|
||||
... try:
|
||||
... raise ValueError(12)
|
||||
... except *TypeError as e:
|
||||
... print('never')
|
||||
... except ValueError as e:
|
||||
... print(f'caught ValueError: {e!r}')
|
||||
... print(f'caught ValueError: {e!r}')
|
||||
...
|
||||
caught ValueError: ValueError(12)
|
||||
>>>
|
||||
|
@ -511,21 +524,25 @@ the original ``ExceptionGroup``:
|
|||
.. code-block::
|
||||
|
||||
>>> try:
|
||||
... try:
|
||||
... raise ExceptionGroup("eg",
|
||||
... [ValueError(1),
|
||||
... TypeError(2),
|
||||
... OSError(3),
|
||||
... ExceptionGroup(
|
||||
... "nested",
|
||||
... [OSError(4), TypeError(5), ValueError(6)])])
|
||||
... except *ValueError as e:
|
||||
... print(f'*ValueError: {e!r}')
|
||||
... raise
|
||||
... except *OSError as e:
|
||||
... print(f'*OSError: {e!r}')
|
||||
... try:
|
||||
... raise ExceptionGroup(
|
||||
... "eg",
|
||||
... [
|
||||
... ValueError(1),
|
||||
... TypeError(2),
|
||||
... OSError(3),
|
||||
... ExceptionGroup(
|
||||
... "nested",
|
||||
... [OSError(4), TypeError(5), ValueError(6)])
|
||||
... ]
|
||||
... )
|
||||
... except *ValueError as e:
|
||||
... print(f'*ValueError: {e!r}')
|
||||
... raise
|
||||
... except *OSError as e:
|
||||
... print(f'*OSError: {e!r}')
|
||||
... except ExceptionGroup as e:
|
||||
... print(repr(e))
|
||||
... print(repr(e))
|
||||
...
|
||||
*ValueError: ExceptionGroup('eg', [ValueError(1), ExceptionGroup('nested', [ValueError(6)])])
|
||||
*OSError: ExceptionGroup('eg', [OSError(3), ExceptionGroup('nested', [OSError(4)])])
|
||||
|
@ -545,22 +562,26 @@ merged with the unhandled ``TypeErrors``.
|
|||
.. code-block::
|
||||
|
||||
>>> try:
|
||||
... try:
|
||||
... raise ExceptionGroup("eg",
|
||||
... [ValueError(1),
|
||||
... TypeError(2),
|
||||
... OSError(3),
|
||||
... ExceptionGroup(
|
||||
... "nested",
|
||||
... [OSError(4), TypeError(5), ValueError(6)])])
|
||||
... except *ValueError as e:
|
||||
... print(f'*ValueError: {e!r}')
|
||||
... raise e
|
||||
... except *OSError as e:
|
||||
... print(f'*OSError: {e!r}')
|
||||
... raise
|
||||
... try:
|
||||
... raise ExceptionGroup(
|
||||
... "eg",
|
||||
... [
|
||||
... ValueError(1),
|
||||
... TypeError(2),
|
||||
... OSError(3),
|
||||
... ExceptionGroup(
|
||||
... "nested",
|
||||
... [OSError(4), TypeError(5), ValueError(6)])
|
||||
... ]
|
||||
... )
|
||||
... except *ValueError as e:
|
||||
... print(f'*ValueError: {e!r}')
|
||||
... raise e
|
||||
... except *OSError as e:
|
||||
... print(f'*OSError: {e!r}')
|
||||
... raise
|
||||
... except ExceptionGroup as e:
|
||||
... traceback.print_exception(e)
|
||||
... traceback.print_exception(e)
|
||||
...
|
||||
*ValueError: ExceptionGroup('eg', [ValueError(1), ExceptionGroup('nested', [ValueError(6)])])
|
||||
*OSError: ExceptionGroup('eg', [OSError(3), ExceptionGroup('nested', [OSError(4)])])
|
||||
|
@ -606,12 +627,12 @@ it into the new ``ExceptionGroup``.
|
|||
.. code-block::
|
||||
|
||||
>>> try:
|
||||
... try:
|
||||
... raise ExceptionGroup("one", [ValueError('a'), TypeError('b')])
|
||||
... except *ValueError:
|
||||
... raise ExceptionGroup("two", [KeyError('x'), KeyError('y')])
|
||||
... try:
|
||||
... raise ExceptionGroup("one", [ValueError('a'), TypeError('b')])
|
||||
... except *ValueError:
|
||||
... raise ExceptionGroup("two", [KeyError('x'), KeyError('y')])
|
||||
... except BaseException as e:
|
||||
... traceback.print_exception(e)
|
||||
... traceback.print_exception(e)
|
||||
...
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 3, in <module>
|
||||
|
@ -651,12 +672,12 @@ chaining:
|
|||
.. code-block::
|
||||
|
||||
>>> try:
|
||||
... try:
|
||||
... raise TypeError('bad type')
|
||||
... except *TypeError as e:
|
||||
... raise ValueError('bad value') from e
|
||||
... try:
|
||||
... raise TypeError('bad type')
|
||||
... except *TypeError as e:
|
||||
... raise ValueError('bad value') from e
|
||||
... except ExceptionGroup as e:
|
||||
... traceback.print_exception(e)
|
||||
... traceback.print_exception(e)
|
||||
...
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 3, in <module>
|
||||
|
@ -682,14 +703,14 @@ other clauses from the same ``try`` statement:
|
|||
.. code-block::
|
||||
|
||||
>>> try:
|
||||
... try:
|
||||
... raise TypeError(1)
|
||||
... except *TypeError:
|
||||
... raise ValueError(2) # <- not caught in the next clause
|
||||
... except *ValueError:
|
||||
... print('never')
|
||||
... try:
|
||||
... raise TypeError(1)
|
||||
... except *TypeError:
|
||||
... raise ValueError(2) # <- not caught in the next clause
|
||||
... except *ValueError:
|
||||
... print('never')
|
||||
... except ExceptionGroup as e:
|
||||
... traceback.print_exception(e)
|
||||
... traceback.print_exception(e)
|
||||
...
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 3, in <module>
|
||||
|
@ -717,10 +738,10 @@ direct child of the new ``ExceptionGroup`` created for that:
|
|||
.. code-block::
|
||||
|
||||
>>> try:
|
||||
... try:
|
||||
... raise ExceptionGroup("eg", [ValueError('a')])
|
||||
... except *ValueError:
|
||||
... raise KeyError('x')
|
||||
... try:
|
||||
... raise ExceptionGroup("eg", [ValueError('a')])
|
||||
... except *ValueError:
|
||||
... raise KeyError('x')
|
||||
... except BaseException as e:
|
||||
... traceback.print_exception(e)
|
||||
...
|
||||
|
@ -741,10 +762,10 @@ direct child of the new ``ExceptionGroup`` created for that:
|
|||
KeyError: 'x'
|
||||
>>>
|
||||
>>> try:
|
||||
... try:
|
||||
... raise ExceptionGroup("eg", [ValueError('a'), TypeError('b')])
|
||||
... except *ValueError:
|
||||
... raise KeyError('x')
|
||||
... try:
|
||||
... raise ExceptionGroup("eg", [ValueError('a'), TypeError('b')])
|
||||
... except *ValueError:
|
||||
... raise KeyError('x')
|
||||
... except BaseException as e:
|
||||
... traceback.print_exception(e)
|
||||
...
|
||||
|
@ -780,9 +801,9 @@ while letting all other exceptions propagate.
|
|||
.. code-block::
|
||||
|
||||
try:
|
||||
low_level_os_operation()
|
||||
low_level_os_operation()
|
||||
except *OSerror as errors:
|
||||
raise errors.subgroup(lambda e: e.errno != errno.EPIPE) from None
|
||||
raise errors.subgroup(lambda e: e.errno != errno.EPIPE) from None
|
||||
|
||||
|
||||
Caught Exception Objects
|
||||
|
@ -798,14 +819,13 @@ likely be lost:
|
|||
>>> eg = ExceptionGroup("eg", [TypeError(12)])
|
||||
>>> eg.foo = 'foo'
|
||||
>>> try:
|
||||
... raise eg
|
||||
... raise eg
|
||||
... except *TypeError as e:
|
||||
... e.foo = 'bar'
|
||||
... # ^----------- ``e`` is an ephemeral object that might get
|
||||
>>> # destroyed after the ``except*`` clause.
|
||||
... e.foo = 'bar'
|
||||
... # ^----------- ``e`` is an ephemeral object that might get
|
||||
>>> # destroyed after the ``except*`` clause.
|
||||
>>> eg.foo
|
||||
'foo'
|
||||
>>>
|
||||
|
||||
|
||||
Forbidden Combinations
|
||||
|
@ -818,11 +838,11 @@ It is not possible to use both traditional ``except`` blocks and the new
|
|||
.. code-block::
|
||||
|
||||
try:
|
||||
...
|
||||
...
|
||||
except ValueError:
|
||||
pass
|
||||
pass
|
||||
except *CancelledError: # <- SyntaxError:
|
||||
pass # combining ``except`` and ``except*``
|
||||
pass # combining ``except`` and ``except*``
|
||||
# is prohibited
|
||||
|
||||
It is possible to catch the ``ExceptionGroup`` type with ``except``, but not
|
||||
|
@ -831,14 +851,14 @@ with ``except*`` because the latter is ambiguous:
|
|||
.. code-block::
|
||||
|
||||
try:
|
||||
...
|
||||
...
|
||||
except ExceptionGroup: # <- This works
|
||||
pass
|
||||
pass
|
||||
|
||||
try:
|
||||
...
|
||||
...
|
||||
except *ExceptionGroup: # <- Runtime error
|
||||
pass
|
||||
pass
|
||||
|
||||
|
||||
An empty "match anything" ``except*`` block is not supported as its meaning may
|
||||
|
@ -847,9 +867,9 @@ be confusing:
|
|||
.. code-block::
|
||||
|
||||
try:
|
||||
...
|
||||
...
|
||||
except*: # <- SyntaxError
|
||||
pass
|
||||
pass
|
||||
|
||||
|
||||
``continue``, ``break``, and ``return`` are disallowed in ``except*`` clauses,
|
||||
|
@ -980,20 +1000,20 @@ occurred, and would use the traditional ``except``:
|
|||
.. code-block::
|
||||
|
||||
try:
|
||||
dct[key]
|
||||
dct[key]
|
||||
except KeyError:
|
||||
# handle the exception
|
||||
# handle the exception
|
||||
|
||||
It is unlikely that asyncio users would want to do something like this:
|
||||
|
||||
.. code-block::
|
||||
|
||||
try:
|
||||
async with asyncio.TaskGroup() as g:
|
||||
g.create_task(task1); g.create_task(task2)
|
||||
async with asyncio.TaskGroup() as g:
|
||||
g.create_task(task1); g.create_task(task2)
|
||||
except *KeyError:
|
||||
# handling KeyError here is meaningless, there's
|
||||
# no context to do anything with it but to log it.
|
||||
# handling KeyError here is meaningless, there's
|
||||
# no context to do anything with it but to log it.
|
||||
|
||||
When a program handles a collection of exceptions that were aggregated into
|
||||
an exception group, it would not typically attempt to recover from any
|
||||
|
@ -1031,12 +1051,12 @@ separate code block to handle each case:
|
|||
.. code-block::
|
||||
|
||||
try:
|
||||
try:
|
||||
...
|
||||
except SomeError:
|
||||
# handle the naked exception
|
||||
try:
|
||||
...
|
||||
except SomeError:
|
||||
# handle the naked exception
|
||||
except *SomeError:
|
||||
# handle the ExceptionGroup
|
||||
# handle the ExceptionGroup
|
||||
|
||||
|
||||
Allow mixing ``except:`` and ``except*:`` in the same ``try``
|
||||
|
|
Loading…
Reference in New Issue