gh-95975: Move except/*/finally ref labels to more precise locations (GH-95976)

* gh-95975: Move except/*/finally ref labels to more precise locations

* Add section headers to fix :keyword: role and aid navigation

* Move see also to the introduction rather than a particular subsection

* Fix other minor Sphinx syntax issues with except

Co-authored-by: Ezio Melotti <ezio.melotti@gmail.com>

* Suppress redundant link to same section for except too

* Don't link try/except/else/finally keywords if in the same section

* Format try/except/finally as keywords in modified sections

Co-authored-by: Ezio Melotti <ezio.melotti@gmail.com>
(cherry picked from commit dcc82331c8)

Co-authored-by: C.A.M. Gerlach <CAM.Gerlach@Gerlach.CAM>
This commit is contained in:
Miss Islington (bot) 2022-10-01 22:20:43 -07:00 committed by GitHub
parent dbde686a49
commit 1fa848ac39
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -199,10 +199,8 @@ returns the list ``[0, 1, 2]``.
.. versionchanged:: 3.11 .. versionchanged:: 3.11
Starred elements are now allowed in the expression list. Starred elements are now allowed in the expression list.
.. _try: .. _try:
.. _except:
.. _except_star:
.. _finally:
The :keyword:`!try` statement The :keyword:`!try` statement
============================= =============================
@ -215,7 +213,7 @@ The :keyword:`!try` statement
keyword: as keyword: as
single: : (colon); compound statement single: : (colon); compound statement
The :keyword:`try` statement specifies exception handlers and/or cleanup code The :keyword:`!try` statement specifies exception handlers and/or cleanup code
for a group of statements: for a group of statements:
.. productionlist:: python-grammar .. productionlist:: python-grammar
@ -231,40 +229,56 @@ for a group of statements:
try3_stmt: "try" ":" `suite` try3_stmt: "try" ":" `suite`
: "finally" ":" `suite` : "finally" ":" `suite`
Additional information on exceptions can be found in section :ref:`exceptions`,
and information on using the :keyword:`raise` statement to generate exceptions
may be found in section :ref:`raise`.
The :keyword:`except` clause(s) specify one or more exception handlers. When no
.. _except:
:keyword:`!except` clause
-------------------------
The :keyword:`!except` clause(s) specify one or more exception handlers. When no
exception occurs in the :keyword:`try` clause, no exception handler is executed. exception occurs in the :keyword:`try` clause, no exception handler is executed.
When an exception occurs in the :keyword:`!try` suite, a search for an exception When an exception occurs in the :keyword:`!try` suite, a search for an exception
handler is started. This search inspects the except clauses in turn until one handler is started. This search inspects the :keyword:`!except` clauses in turn
is found that matches the exception. An expression-less except clause, if until one is found that matches the exception.
present, must be last; it matches any exception. For an except clause with an An expression-less :keyword:`!except` clause, if present, must be last;
expression, that expression is evaluated, and the clause matches the exception it matches any exception.
For an :keyword:`!except` clause with an expression,
that expression is evaluated, and the clause matches the exception
if the resulting object is "compatible" with the exception. An object is if the resulting object is "compatible" with the exception. An object is
compatible with an exception if the object is the class or a compatible with an exception if the object is the class or a
:term:`non-virtual base class <abstract base class>` of the exception object, :term:`non-virtual base class <abstract base class>` of the exception object,
or a tuple containing an item that is the class or a non-virtual base class or a tuple containing an item that is the class or a non-virtual base class
of the exception object. of the exception object.
If no except clause matches the exception, the search for an exception handler If no :keyword:`!except` clause matches the exception,
the search for an exception handler
continues in the surrounding code and on the invocation stack. [#]_ continues in the surrounding code and on the invocation stack. [#]_
If the evaluation of an expression in the header of an except clause raises an If the evaluation of an expression
exception, the original search for a handler is canceled and a search starts for in the header of an :keyword:`!except` clause raises an exception,
the original search for a handler is canceled and a search starts for
the new exception in the surrounding code and on the call stack (it is treated the new exception in the surrounding code and on the call stack (it is treated
as if the entire :keyword:`try` statement raised the exception). as if the entire :keyword:`try` statement raised the exception).
.. index:: single: as; except clause .. index:: single: as; except clause
When a matching except clause is found, the exception is assigned to the target When a matching :keyword:`!except` clause is found,
specified after the :keyword:`!as` keyword in that except clause, if present, and the exception is assigned to the target
the except clause's suite is executed. All except clauses must have an specified after the :keyword:`!as` keyword in that :keyword:`!except` clause,
executable block. When the end of this block is reached, execution continues if present, and the :keyword:`!except` clause's suite is executed.
normally after the entire try statement. (This means that if two nested All :keyword:`!except` clauses must have an executable block.
handlers exist for the same exception, and the exception occurs in the try When the end of this block is reached, execution continues
clause of the inner handler, the outer handler will not handle the exception.) normally after the entire :keyword:`try` statement.
(This means that if two nested handlers exist for the same exception,
and the exception occurs in the :keyword:`!try` clause of the inner handler,
the outer handler will not handle the exception.)
When an exception has been assigned using ``as target``, it is cleared at the When an exception has been assigned using ``as target``, it is cleared at the
end of the except clause. This is as if :: end of the :keyword:`!except` clause. This is as if ::
except E as N: except E as N:
foo foo
@ -278,7 +292,8 @@ was translated to ::
del N del N
This means the exception must be assigned to a different name to be able to This means the exception must be assigned to a different name to be able to
refer to it after the except clause. Exceptions are cleared because with the refer to it after the :keyword:`!except` clause.
Exceptions are cleared because with the
traceback attached to them, they form a reference cycle with the stack frame, traceback attached to them, they form a reference cycle with the stack frame,
keeping all locals in that frame alive until the next garbage collection occurs. keeping all locals in that frame alive until the next garbage collection occurs.
@ -286,7 +301,8 @@ keeping all locals in that frame alive until the next garbage collection occurs.
module: sys module: sys
object: traceback object: traceback
Before an except clause's suite is executed, details about the exception are Before an :keyword:`!except` clause's suite is executed,
details about the exception are
stored in the :mod:`sys` module and can be accessed via :func:`sys.exc_info`. stored in the :mod:`sys` module and can be accessed via :func:`sys.exc_info`.
:func:`sys.exc_info` returns a 3-tuple consisting of the exception class, the :func:`sys.exc_info` returns a 3-tuple consisting of the exception class, the
exception instance and a traceback object (see section :ref:`types`) identifying exception instance and a traceback object (see section :ref:`types`) identifying
@ -312,17 +328,24 @@ when leaving an exception handler::
>>> print(sys.exc_info()) >>> print(sys.exc_info())
(None, None, None) (None, None, None)
.. index:: .. index::
keyword: except_star keyword: except_star
The :keyword:`except*<except_star>` clause(s) are used for handling .. _except_star:
:exc:`ExceptionGroup`\ s. The exception type for matching is interpreted as in
:keyword:`!except*` clause
--------------------------
The :keyword:`!except*` clause(s) are used for handling
:exc:`ExceptionGroup`\s. The exception type for matching is interpreted as in
the case of :keyword:`except`, but in the case of exception groups we can have the case of :keyword:`except`, but in the case of exception groups we can have
partial matches when the type matches some of the exceptions in the group. partial matches when the type matches some of the exceptions in the group.
This means that multiple except* clauses can execute, each handling part of This means that multiple :keyword:`!except*` clauses can execute,
the exception group. Each clause executes once and handles an exception group each handling part of the exception group.
Each clause executes once and handles an exception group
of all matching exceptions. Each exception in the group is handled by at most of all matching exceptions. Each exception in the group is handled by at most
one except* clause, the first that matches it. :: one :keyword:`!except*` clause, the first that matches it. ::
>>> try: >>> try:
... raise ExceptionGroup("eg", ... raise ExceptionGroup("eg",
@ -342,15 +365,16 @@ one except* clause, the first that matches it. ::
+------------------------------------ +------------------------------------
>>> >>>
Any remaining exceptions that were not handled by any except* clause Any remaining exceptions that were not handled by any :keyword:`!except*`
are re-raised at the end, combined into an exception group along with clause are re-raised at the end, combined into an exception group along with
all exceptions that were raised from within except* clauses. all exceptions that were raised from within :keyword:`!except*` clauses.
An except* clause must have a matching type, and this type cannot be a An :keyword:`!except*` clause must have a matching type,
subclass of :exc:`BaseExceptionGroup`. It is not possible to mix except and this type cannot be a subclass of :exc:`BaseExceptionGroup`.
and except* in the same :keyword:`try`. :keyword:`break`, It is not possible to mix :keyword:`except` and :keyword:`!except*`
:keyword:`continue` and :keyword:`return` cannot appear in an except* in the same :keyword:`try`.
clause. :keyword:`break`, :keyword:`continue` and :keyword:`return`
cannot appear in an :keyword:`!except*` clause.
.. index:: .. index::
@ -359,17 +383,28 @@ one except* clause, the first that matches it. ::
statement: break statement: break
statement: continue statement: continue
.. _except_else:
:keyword:`!else` clause
-----------------------
The optional :keyword:`!else` clause is executed if the control flow leaves the The optional :keyword:`!else` clause is executed if the control flow leaves the
:keyword:`try` suite, no exception was raised, and no :keyword:`return`, :keyword:`try` suite, no exception was raised, and no :keyword:`return`,
:keyword:`continue`, or :keyword:`break` statement was executed. Exceptions in :keyword:`continue`, or :keyword:`break` statement was executed. Exceptions in
the :keyword:`!else` clause are not handled by the preceding :keyword:`except` the :keyword:`!else` clause are not handled by the preceding :keyword:`except`
clauses. clauses.
.. index:: keyword: finally .. index:: keyword: finally
If :keyword:`finally` is present, it specifies a 'cleanup' handler. The .. _finally:
:keyword:`!finally` clause
--------------------------
If :keyword:`!finally` is present, it specifies a 'cleanup' handler. The
:keyword:`try` clause is executed, including any :keyword:`except` and :keyword:`try` clause is executed, including any :keyword:`except` and
:keyword:`!else` clauses. If an exception occurs in any of the clauses and is :keyword:`else` clauses. If an exception occurs in any of the clauses and is
not handled, the exception is temporarily saved. The :keyword:`!finally` clause not handled, the exception is temporarily saved. The :keyword:`!finally` clause
is executed. If there is a saved exception it is re-raised at the end of the is executed. If there is a saved exception it is re-raised at the end of the
:keyword:`!finally` clause. If the :keyword:`!finally` clause raises another :keyword:`!finally` clause. If the :keyword:`!finally` clause raises another
@ -387,7 +422,7 @@ or :keyword:`continue` statement, the saved exception is discarded::
42 42
The exception information is not available to the program during execution of The exception information is not available to the program during execution of
the :keyword:`finally` clause. the :keyword:`!finally` clause.
.. index:: .. index::
statement: return statement: return
@ -396,10 +431,10 @@ the :keyword:`finally` clause.
When a :keyword:`return`, :keyword:`break` or :keyword:`continue` statement is When a :keyword:`return`, :keyword:`break` or :keyword:`continue` statement is
executed in the :keyword:`try` suite of a :keyword:`!try`...\ :keyword:`!finally` executed in the :keyword:`try` suite of a :keyword:`!try`...\ :keyword:`!finally`
statement, the :keyword:`finally` clause is also executed 'on the way out.' statement, the :keyword:`!finally` clause is also executed 'on the way out.'
The return value of a function is determined by the last :keyword:`return` The return value of a function is determined by the last :keyword:`return`
statement executed. Since the :keyword:`finally` clause always executes, a statement executed. Since the :keyword:`!finally` clause always executes, a
:keyword:`!return` statement executed in the :keyword:`!finally` clause will :keyword:`!return` statement executed in the :keyword:`!finally` clause will
always be the last one executed:: always be the last one executed::
@ -412,13 +447,9 @@ always be the last one executed::
>>> foo() >>> foo()
'finally' 'finally'
Additional information on exceptions can be found in section :ref:`exceptions`,
and information on using the :keyword:`raise` statement to generate exceptions
may be found in section :ref:`raise`.
.. versionchanged:: 3.8 .. versionchanged:: 3.8
Prior to Python 3.8, a :keyword:`continue` statement was illegal in the Prior to Python 3.8, a :keyword:`continue` statement was illegal in the
:keyword:`finally` clause due to a problem with the implementation. :keyword:`!finally` clause due to a problem with the implementation.
.. _with: .. _with: