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