https://github.com/python/cpython/commit/443c0cd17c5b0c71ee45c3621777454c6b8b0cbd
commit: 443c0cd17c5b0c71ee45c3621777454c6b8b0cbd
branch: main
author: Adam Turner <9087854+aa-tur...@users.noreply.github.com>
committer: AA-Turner <9087854+aa-tur...@users.noreply.github.com>
date: 2025-03-20T15:35:20Z
summary:

gh-127833: Use `productionlist` nodes to implement the `grammar-snippet` 
directive (#130376)

Co-authored-by: Petr Viktorin <encu...@gmail.com>
Co-authored-by: Blaise Pabon <bla...@gmail.com>

files:
M Doc/tools/extensions/grammar_snippet.py
M Lib/pydoc_data/topics.py

diff --git a/Doc/tools/extensions/grammar_snippet.py 
b/Doc/tools/extensions/grammar_snippet.py
index 03c7e7ce2f4228..1e059f111e4091 100644
--- a/Doc/tools/extensions/grammar_snippet.py
+++ b/Doc/tools/extensions/grammar_snippet.py
@@ -13,8 +13,8 @@
 from sphinx.util.nodes import make_id
 
 if TYPE_CHECKING:
-    from collections.abc import Sequence
-    from typing import Any
+    from collections.abc import Iterable, Iterator, Sequence
+    from typing import Any, Final
 
     from docutils.nodes import Node
     from sphinx.application import Sphinx
@@ -41,98 +41,140 @@ class GrammarSnippetBase(SphinxDirective):
 
     # The option/argument handling is left to the individual classes.
 
+    grammar_re: Final = re.compile(
+        r"""
+            (?P<rule_name>^[a-zA-Z0-9_]+)     # identifier at start of line
+            (?=:)                             # ... followed by a colon
+        |
+            (?P<rule_ref>`[^\s`]+`)           # identifier in backquotes
+        |
+            (?P<single_quoted>'[^']*')        # string in 'quotes'
+        |
+            (?P<double_quoted>"[^"]*")        # string in "quotes"
+        """,
+        re.VERBOSE,
+    )
+
     def make_grammar_snippet(
         self, options: dict[str, Any], content: Sequence[str]
-    ) -> list[nodes.paragraph]:
+    ) -> list[addnodes.productionlist]:
         """Create a literal block from options & content."""
 
         group_name = options['group']
-
-        # Docutils elements have a `rawsource` attribute that is supposed to be
-        # set to the original ReST source.
-        # Sphinx does the following with it:
-        # - if it's empty, set it to `self.astext()`
-        # - if it matches `self.astext()` when generating the output,
-        #   apply syntax highlighting (which is based on the plain-text content
-        #   and thus discards internal formatting, like references).
-        # To get around this, we set it to this non-empty string:
-        rawsource = 'You should not see this.'
-
-        literal = nodes.literal_block(
-            rawsource,
+        node_location = self.get_location()
+        production_nodes = []
+        for rawsource, production_defs in self.production_definitions(content):
+            production = self.make_production(
+                rawsource,
+                production_defs,
+                group_name=group_name,
+                location=node_location,
+            )
+            production_nodes.append(production)
+
+        node = addnodes.productionlist(
             '',
+            *production_nodes,
+            support_smartquotes=False,
             classes=['highlight'],
         )
+        self.set_source_info(node)
+        return [node]
 
-        grammar_re = re.compile(
-            r"""
-                (?P<rule_name>^[a-zA-Z0-9_]+)     # identifier at start of line
-                (?=:)                             # ... followed by a colon
-            |
-                (?P<rule_ref>`[^\s`]+`)           # identifier in backquotes
-            |
-                (?P<single_quoted>'[^']*')        # string in 'quotes'
-            |
-                (?P<double_quoted>"[^"]*")        # string in "quotes"
-            """,
-            re.VERBOSE,
-        )
-
-        for line in content:
+    def production_definitions(
+        self, lines: Iterable[str], /
+    ) -> Iterator[tuple[str, list[tuple[str, str]]]]:
+        """Yield pairs of rawsource and production content dicts."""
+        production_lines: list[str] = []
+        production_content: list[tuple[str, str]] = []
+        for line in lines:
+            # If this line is the start of a new rule (text in the column 1),
+            # emit the current production and start a new one.
+            if not line[:1].isspace():
+                rawsource = '\n'.join(production_lines)
+                production_lines.clear()
+                if production_content:
+                    yield rawsource, production_content
+                    production_content = []
+
+            # Append the current line for the raw source
+            production_lines.append(line)
+
+            # Parse the line into constituent parts
             last_pos = 0
-            for match in grammar_re.finditer(line):
+            for match in self.grammar_re.finditer(line):
                 # Handle text between matches
                 if match.start() > last_pos:
-                    literal += nodes.Text(line[last_pos : match.start()])
+                    unmatched_text = line[last_pos : match.start()]
+                    production_content.append(('text', unmatched_text))
                 last_pos = match.end()
 
-                # Handle matches
-                group_dict = {
-                    name: content
-                    for name, content in match.groupdict().items()
+                # Handle matches.
+                # After filtering None (non-matches), exactly one groupdict()
+                # entry should remain.
+                [(re_group_name, content)] = (
+                    (re_group_name, content)
+                    for re_group_name, content in match.groupdict().items()
                     if content is not None
-                }
-                match group_dict:
-                    case {'rule_name': name}:
-                        literal += self.make_link_target_for_token(
-                            group_name, name
-                        )
-                    case {'rule_ref': ref_text}:
-                        literal += token_xrefs(ref_text, group_name)
-                    case {'single_quoted': name} | {'double_quoted': name}:
-                        literal += snippet_string_node('', name)
-                    case _:
-                        raise ValueError('unhandled match')
-            literal += nodes.Text(line[last_pos:] + '\n')
-
-        node = nodes.paragraph(
-            '',
-            '',
-            literal,
-        )
+                )
+                production_content.append((re_group_name, content))
+            production_content.append(('text', line[last_pos:] + '\n'))
 
-        return [node]
+        # Emit the final production
+        if production_content:
+            rawsource = '\n'.join(production_lines)
+            yield rawsource, production_content
 
-    def make_link_target_for_token(
-        self, group_name: str, name: str
+    def make_production(
+        self,
+        rawsource: str,
+        production_defs: list[tuple[str, str]],
+        *,
+        group_name: str,
+        location: str,
+    ) -> addnodes.production:
+        """Create a production node from a list of parts."""
+        production_node = addnodes.production(rawsource)
+        for re_group_name, content in production_defs:
+            match re_group_name:
+                case 'rule_name':
+                    production_node += self.make_name_target(
+                        name=content,
+                        production_group=group_name,
+                        location=location,
+                    )
+                case 'rule_ref':
+                    production_node += token_xrefs(content, group_name)
+                case 'single_quoted' | 'double_quoted':
+                    production_node += snippet_string_node('', content)
+                case 'text':
+                    production_node += nodes.Text(content)
+                case _:
+                    raise ValueError(f'unhandled match: {re_group_name!r}')
+        return production_node
+
+    def make_name_target(
+        self,
+        *,
+        name: str,
+        production_group: str,
+        location: str,
     ) -> addnodes.literal_strong:
-        """Return a literal node which is a link target for the given token."""
-        name_node = addnodes.literal_strong()
+        """Make a link target for the given production."""
 
         # Cargo-culted magic to make `name_node` a link target
         # similar to Sphinx `production`.
         # This needs to be the same as what Sphinx does
         # to avoid breaking existing links.
-        domain = self.env.domains['std']
-        obj_name = f"{group_name}:{name}"
-        prefix = f'grammar-token-{group_name}'
+
+        name_node = addnodes.literal_strong(name, name)
+        prefix = f'grammar-token-{production_group}'
         node_id = make_id(self.env, self.state.document, prefix, name)
         name_node['ids'].append(node_id)
         self.state.document.note_implicit_target(name_node, name_node)
-        domain.note_object('token', obj_name, node_id, location=name_node)
-
-        text_node = nodes.Text(name)
-        name_node += text_node
+        obj_name = f'{production_group}:{name}' if production_group else name
+        std = self.env.domains.standard_domain
+        std.note_object('token', obj_name, node_id, location=location)
         return name_node
 
 
@@ -168,7 +210,7 @@ class GrammarSnippetDirective(GrammarSnippetBase):
     optional_arguments = 1
     final_argument_whitespace = True
 
-    def run(self) -> list[nodes.paragraph]:
+    def run(self) -> list[addnodes.productionlist]:
         return self.make_grammar_snippet(self.options, self.content)
 
 
@@ -187,7 +229,7 @@ class CompatProductionList(GrammarSnippetBase):
     final_argument_whitespace = True
     option_spec = {}
 
-    def run(self) -> list[nodes.paragraph]:
+    def run(self) -> list[addnodes.productionlist]:
         # The "content" of a productionlist is actually the first and only
         # argument. The first line is the group; the rest is the content lines.
         lines = self.arguments[0].splitlines()
diff --git a/Lib/pydoc_data/topics.py b/Lib/pydoc_data/topics.py
index d392efec5c12c2..f949b96aa56bb1 100644
--- a/Lib/pydoc_data/topics.py
+++ b/Lib/pydoc_data/topics.py
@@ -1,4 +1,4 @@
-# Autogenerated by Sphinx on Fri Mar 14 15:32:05 2025
+# Autogenerated by Sphinx on Wed Mar 19 18:40:00 2025
 # as part of the release process.
 
 topics = {
@@ -8,7 +8,7 @@
 Assert statements are a convenient way to insert debugging assertions
 into a program:
 
-   **assert_stmt**: "assert" "expression" ["," "expression"]
+   assert_stmt: "assert" expression ["," expression]
 
 The simple form, "assert expression", is equivalent to
 
@@ -39,15 +39,15 @@
 Assignment statements are used to (re)bind names to values and to
 modify attributes or items of mutable objects:
 
-   **assignment_stmt**: ("target_list" "=")+ ("starred_expression" | 
"yield_expression")
-   **target_list**:     "target" ("," "target")* [","]
-   **target**:          "identifier"
-                    | "(" ["target_list"] ")"
-                    | "[" ["target_list"] "]"
-                    | "attributeref"
-                    | "subscription"
-                    | "slicing"
-                    | "*" "target"
+   assignment_stmt: (target_list "=")+ (starred_expression | yield_expression)
+   target_list:     target ("," target)* [","]
+   target:          identifier
+                    | "(" [target_list] ")"
+                    | "[" [target_list] "]"
+                    | attributeref
+                    | subscription
+                    | slicing
+                    | "*" target
 
 (See section Primaries for the syntax definitions for *attributeref*,
 *subscription*, and *slicing*.)
@@ -195,9 +195,9 @@ class Cls:
 Augmented assignment is the combination, in a single statement, of a
 binary operation and an assignment statement:
 
-   **augmented_assignment_stmt**: "augtarget" "augop" ("expression_list" | 
"yield_expression")
-   **augtarget**:                 "identifier" | "attributeref" | 
"subscription" | "slicing"
-   **augop**:                     "+=" | "-=" | "*=" | "@=" | "/=" | "//=" | 
"%=" | "**="
+   augmented_assignment_stmt: augtarget augop (expression_list | 
yield_expression)
+   augtarget:                 identifier | attributeref | subscription | 
slicing
+   augop:                     "+=" | "-=" | "*=" | "@=" | "/=" | "//=" | "%=" 
| "**="
                               | ">>=" | "<<=" | "&=" | "^=" | "|="
 
 (See section Primaries for the syntax definitions of the last three
@@ -239,8 +239,8 @@ class and instance attributes applies as for regular 
assignments.
 a variable or attribute annotation and an optional assignment
 statement:
 
-   **annotated_assignment_stmt**: "augtarget" ":" "expression"
-                              ["=" ("starred_expression" | "yield_expression")]
+   annotated_assignment_stmt: augtarget ":" expression
+                              ["=" (starred_expression | yield_expression)]
 
 The difference from normal Assignment statements is that only a single
 target is allowed.
@@ -289,7 +289,7 @@ class and instance attributes applies as for regular 
assignments.
     'assignment-expressions': r'''Assignment expressions
 **********************
 
-   **assignment_expression**: ["identifier" ":="] "expression"
+   assignment_expression: [identifier ":="] expression
 
 An assignment expression (sometimes also called a “named expression”
 or “walrus”) assigns an "expression" to an "identifier", while also
@@ -324,8 +324,8 @@ class and instance attributes applies as for regular 
assignments.
 Coroutine function definition
 =============================
 
-   **async_funcdef**: ["decorators"] "async" "def" "funcname" "(" 
["parameter_list"] ")"
-                  ["->" "expression"] ":" "suite"
+   async_funcdef: [decorators] "async" "def" funcname "(" [parameter_list] ")"
+                  ["->" expression] ":" suite
 
 Execution of Python coroutines can be suspended and resumed at many
 points (see *coroutine*). "await" expressions, "async for" and "async
@@ -351,7 +351,7 @@ async def func(param1, param2):
 The "async for" statement
 =========================
 
-   **async_for_stmt**: "async" "for_stmt"
+   async_for_stmt: "async" for_stmt
 
 An *asynchronous iterable* provides an "__aiter__" method that
 directly returns an *asynchronous iterator*, which can call
@@ -392,7 +392,7 @@ async def func(param1, param2):
 The "async with" statement
 ==========================
 
-   **async_with_stmt**: "async" "with_stmt"
+   async_with_stmt: "async" with_stmt
 
 An *asynchronous context manager* is a *context manager* that is able
 to suspend execution in its *enter* and *exit* methods.
@@ -492,8 +492,8 @@ async def func(param1, param2):
 Python supports string and bytes literals and various numeric
 literals:
 
-   **literal**: "stringliteral" | "bytesliteral"
-            | "integer" | "floatnumber" | "imagnumber"
+   literal: stringliteral | bytesliteral
+            | integer | floatnumber | imagnumber
 
 Evaluation of a literal yields an object of the given type (string,
 bytes, integer, floating-point number, complex number) with the given
@@ -842,7 +842,7 @@ class derived from a ""variable-length" built-in type" such 
as
 
 An attribute reference is a primary followed by a period and a name:
 
-   **attributeref**: "primary" "." "identifier"
+   attributeref: primary "." identifier
 
 The primary must evaluate to an object of a type that supports
 attribute references, which most objects do.  This object is then
@@ -864,9 +864,9 @@ class derived from a ""variable-length" built-in type" such 
as
 Augmented assignment is the combination, in a single statement, of a
 binary operation and an assignment statement:
 
-   **augmented_assignment_stmt**: "augtarget" "augop" ("expression_list" | 
"yield_expression")
-   **augtarget**:                 "identifier" | "attributeref" | 
"subscription" | "slicing"
-   **augop**:                     "+=" | "-=" | "*=" | "@=" | "/=" | "//=" | 
"%=" | "**="
+   augmented_assignment_stmt: augtarget augop (expression_list | 
yield_expression)
+   augtarget:                 identifier | attributeref | subscription | 
slicing
+   augop:                     "+=" | "-=" | "*=" | "@=" | "/=" | "//=" | "%=" 
| "**="
                               | ">>=" | "<<=" | "&=" | "^=" | "|="
 
 (See section Primaries for the syntax definitions of the last three
@@ -906,7 +906,7 @@ class and instance attributes applies as for regular 
assignments.
 Suspend the execution of *coroutine* on an *awaitable* object. Can
 only be used inside a *coroutine function*.
 
-   **await_expr**: "await" "primary"
+   await_expr: "await" primary
 
 Added in version 3.5.
 ''',
@@ -919,10 +919,10 @@ class and instance attributes applies as for regular 
assignments.
 levels, one for multiplicative operators and one for additive
 operators:
 
-   **m_expr**: "u_expr" | "m_expr" "*" "u_expr" | "m_expr" "@" "m_expr" |
-           "m_expr" "//" "u_expr" | "m_expr" "/" "u_expr" |
-           "m_expr" "%" "u_expr"
-   **a_expr**: "m_expr" | "a_expr" "+" "m_expr" | "a_expr" "-" "m_expr"
+   m_expr: u_expr | m_expr "*" u_expr | m_expr "@" m_expr |
+           m_expr "//" u_expr | m_expr "/" u_expr |
+           m_expr "%" u_expr
+   a_expr: m_expr | a_expr "+" m_expr | a_expr "-" m_expr
 
 The "*" (multiplication) operator yields the product of its arguments.
 The arguments must either both be numbers, or one argument must be an
@@ -1010,9 +1010,9 @@ class and instance attributes applies as for regular 
assignments.
 
 Each of the three bitwise operations has a different priority level:
 
-   **and_expr**: "shift_expr" | "and_expr" "&" "shift_expr"
-   **xor_expr**: "and_expr" | "xor_expr" "^" "and_expr"
-   **or_expr**:  "xor_expr" | "or_expr" "|" "xor_expr"
+   and_expr: shift_expr | and_expr "&" shift_expr
+   xor_expr: and_expr | xor_expr "^" and_expr
+   or_expr:  xor_expr | or_expr "|" xor_expr
 
 The "&" operator yields the bitwise AND of its arguments, which must
 be integers or one of them must be a custom object overriding
@@ -1077,9 +1077,9 @@ class and instance attributes applies as for regular 
assignments.
     'booleans': r'''Boolean operations
 ******************
 
-   **or_test**:  "and_test" | "or_test" "or" "and_test"
-   **and_test**: "not_test" | "and_test" "and" "not_test"
-   **not_test**: "comparison" | "not" "not_test"
+   or_test:  and_test | or_test "or" and_test
+   and_test: not_test | and_test "and" not_test
+   not_test: comparison | "not" not_test
 
 In the context of Boolean operations, and also when expressions are
 used by control flow statements, the following values are interpreted
@@ -1111,7 +1111,7 @@ class and instance attributes applies as for regular 
assignments.
     'break': r'''The "break" statement
 *********************
 
-   **break_stmt**: "break"
+   break_stmt: "break"
 
 "break" may only occur syntactically nested in a "for" or "while"
 loop, but not nested in a function or class definition within that
@@ -1143,18 +1143,18 @@ class and instance attributes applies as for regular 
assignments.
 A call calls a callable object (e.g., a *function*) with a possibly
 empty series of *arguments*:
 
-   **call**:                 "primary" "(" ["argument_list" [","] | 
"comprehension"] ")"
-   **argument_list**:        "positional_arguments" ["," 
"starred_and_keywords"]
-                           ["," "keywords_arguments"]
-                         | "starred_and_keywords" ["," "keywords_arguments"]
-                         | "keywords_arguments"
-   **positional_arguments**: positional_item ("," positional_item)*
-   **positional_item**:      "assignment_expression" | "*" "expression"
-   **starred_and_keywords**: ("*" "expression" | "keyword_item")
-                         ("," "*" "expression" | "," "keyword_item")*
-   **keywords_arguments**:   ("keyword_item" | "**" "expression")
-                         ("," "keyword_item" | "," "**" "expression")*
-   **keyword_item**:         "identifier" "=" "expression"
+   call:                 primary "(" [argument_list [","] | comprehension] ")"
+   argument_list:        positional_arguments ["," starred_and_keywords]
+                           ["," keywords_arguments]
+                         | starred_and_keywords ["," keywords_arguments]
+                         | keywords_arguments
+   positional_arguments: positional_item ("," positional_item)*
+   positional_item:      assignment_expression | "*" expression
+   starred_and_keywords: ("*" expression | keyword_item)
+                         ("," "*" expression | "," keyword_item)*
+   keywords_arguments:   (keyword_item | "**" expression)
+                         ("," keyword_item | "," "**" expression)*
+   keyword_item:         identifier "=" expression
 
 An optional trailing comma may be present after the positional and
 keyword arguments but does not affect the semantics.
@@ -1296,9 +1296,9 @@ class and instance attributes applies as for regular 
assignments.
 A class definition defines a class object (see section The standard
 type hierarchy):
 
-   **classdef**:    ["decorators"] "class" "classname" ["type_params"] 
["inheritance"] ":" "suite"
-   **inheritance**: "(" ["argument_list"] ")"
-   **classname**:   "identifier"
+   classdef:    [decorators] "class" classname [type_params] [inheritance] ":" 
suite
+   inheritance: "(" [argument_list] ")"
+   classname:   identifier
 
 A class definition is an executable statement.  The inheritance list
 usually gives a list of base classes (see Metaclasses for more
@@ -1386,8 +1386,8 @@ class attributes; they are shared by instances.  Instance 
attributes
 operation.  Also unlike C, expressions like "a < b < c" have the
 interpretation that is conventional in mathematics:
 
-   **comparison**:    "or_expr" ("comp_operator" "or_expr")*
-   **comp_operator**: "<" | ">" | "==" | ">=" | "<=" | "!="
+   comparison:    or_expr (comp_operator or_expr)*
+   comp_operator: "<" | ">" | "==" | ">=" | "<=" | "!="
                   | "is" ["not"] | ["not"] "in"
 
 Comparisons yield boolean values: "True" or "False". Custom *rich
@@ -1656,20 +1656,20 @@ class attributes; they are shared by instances.  
Instance attributes
 
 Summarizing:
 
-   **compound_stmt**: "if_stmt"
-                  | "while_stmt"
-                  | "for_stmt"
-                  | "try_stmt"
-                  | "with_stmt"
-                  | "match_stmt"
-                  | "funcdef"
-                  | "classdef"
-                  | "async_with_stmt"
-                  | "async_for_stmt"
-                  | "async_funcdef"
-   **suite**:         "stmt_list" NEWLINE | NEWLINE INDENT "statement"+ DEDENT
-   **statement**:     "stmt_list" NEWLINE | "compound_stmt"
-   **stmt_list**:     "simple_stmt" (";" "simple_stmt")* [";"]
+   compound_stmt: if_stmt
+                  | while_stmt
+                  | for_stmt
+                  | try_stmt
+                  | with_stmt
+                  | match_stmt
+                  | funcdef
+                  | classdef
+                  | async_with_stmt
+                  | async_for_stmt
+                  | async_funcdef
+   suite:         stmt_list NEWLINE | NEWLINE INDENT statement+ DEDENT
+   statement:     stmt_list NEWLINE | compound_stmt
+   stmt_list:     simple_stmt (";" simple_stmt)* [";"]
 
 Note that statements always end in a "NEWLINE" possibly followed by a
 "DEDENT".  Also note that optional continuation clauses always begin
@@ -1686,9 +1686,9 @@ class attributes; they are shared by instances.  Instance 
attributes
 
 The "if" statement is used for conditional execution:
 
-   **if_stmt**: "if" "assignment_expression" ":" "suite"
-            ("elif" "assignment_expression" ":" "suite")*
-            ["else" ":" "suite"]
+   if_stmt: "if" assignment_expression ":" suite
+            ("elif" assignment_expression ":" suite)*
+            ["else" ":" suite]
 
 It selects exactly one of the suites by evaluating the expressions one
 by one until one is found to be true (see section Boolean operations
@@ -1704,8 +1704,8 @@ class attributes; they are shared by instances.  Instance 
attributes
 The "while" statement is used for repeated execution as long as an
 expression is true:
 
-   **while_stmt**: "while" "assignment_expression" ":" "suite"
-               ["else" ":" "suite"]
+   while_stmt: "while" assignment_expression ":" suite
+               ["else" ":" suite]
 
 This repeatedly tests the expression and, if it is true, executes the
 first suite; if the expression is false (which may be the first time
@@ -1724,8 +1724,8 @@ class attributes; they are shared by instances.  Instance 
attributes
 The "for" statement is used to iterate over the elements of a sequence
 (such as a string, tuple or list) or other iterable object:
 
-   **for_stmt**: "for" "target_list" "in" "starred_list" ":" "suite"
-             ["else" ":" "suite"]
+   for_stmt: "for" target_list "in" starred_list ":" suite
+             ["else" ":" suite]
 
 The "starred_list" expression is evaluated once; it should yield an
 *iterable* object.  An *iterator* is created for that iterable. The
@@ -1768,17 +1768,17 @@ class attributes; they are shared by instances.  
Instance attributes
 The "try" statement specifies exception handlers and/or cleanup code
 for a group of statements:
 
-   **try_stmt**:  "try1_stmt" | "try2_stmt" | "try3_stmt"
-   **try1_stmt**: "try" ":" "suite"
-              ("except" ["expression" ["as" "identifier"]] ":" "suite")+
-              ["else" ":" "suite"]
-              ["finally" ":" "suite"]
-   **try2_stmt**: "try" ":" "suite"
-              ("except" "*" "expression" ["as" "identifier"] ":" "suite")+
-              ["else" ":" "suite"]
-              ["finally" ":" "suite"]
-   **try3_stmt**: "try" ":" "suite"
-              "finally" ":" "suite"
+   try_stmt:  try1_stmt | try2_stmt | try3_stmt
+   try1_stmt: "try" ":" suite
+              ("except" [expression ["as" identifier]] ":" suite)+
+              ["else" ":" suite]
+              ["finally" ":" suite]
+   try2_stmt: "try" ":" suite
+              ("except" "*" expression ["as" identifier] ":" suite)+
+              ["else" ":" suite]
+              ["finally" ":" suite]
+   try3_stmt: "try" ":" suite
+              "finally" ":" suite
 
 Additional information on exceptions can be found in section
 Exceptions, and information on using the "raise" statement to generate
@@ -1940,16 +1940,13 @@ class attributes; they are shared by instances.  
Instance attributes
 clause.  If the "finally" clause raises another exception, the saved
 exception is set as the context of the new exception. If the "finally"
 clause executes a "return", "break" or "continue" statement, the saved
-exception is discarded:
+exception is discarded. For example, this function returns 42.
 
-   >>> def f():
-   ...     try:
-   ...         1/0
-   ...     finally:
-   ...         return 42
-   ...
-   >>> f()
-   42
+   def f():
+       try:
+           1/0
+       finally:
+           return 42
 
 The exception information is not available to the program during
 execution of the "finally" clause.
@@ -1961,21 +1958,22 @@ class attributes; they are shared by instances.  
Instance attributes
 The return value of a function is determined by the last "return"
 statement executed.  Since the "finally" clause always executes, a
 "return" statement executed in the "finally" clause will always be the
-last one executed:
+last one executed. The following function returns ‘finally’.
 
-   >>> def foo():
-   ...     try:
-   ...         return 'try'
-   ...     finally:
-   ...         return 'finally'
-   ...
-   >>> foo()
-   'finally'
+   def foo():
+       try:
+           return 'try'
+       finally:
+           return 'finally'
 
 Changed in version 3.8: Prior to Python 3.8, a "continue" statement
 was illegal in the "finally" clause due to a problem with the
 implementation.
 
+Changed in version 3.14.0a6 (unreleased): The compiler emits a
+"SyntaxWarning" when a "return", "break" or "continue" appears in a
+"finally" block (see **PEP 765**).
+
 
 The "with" statement
 ====================
@@ -1985,9 +1983,9 @@ class attributes; they are shared by instances.  Instance 
attributes
 Context Managers). This allows common "try"…"except"…"finally" usage
 patterns to be encapsulated for convenient reuse.
 
-   **with_stmt**:          "with" ( "(" "with_stmt_contents" ","? ")" | 
"with_stmt_contents" ) ":" "suite"
-   **with_stmt_contents**: "with_item" ("," "with_item")*
-   **with_item**:          "expression" ["as" "target"]
+   with_stmt:          "with" ( "(" with_stmt_contents ","? ")" | 
with_stmt_contents ) ":" suite
+   with_stmt_contents: with_item ("," with_item)*
+   with_item:          expression ["as" target]
 
 The execution of the "with" statement with one “item” proceeds as
 follows:
@@ -2093,10 +2091,10 @@ class attributes; they are shared by instances.  
Instance attributes
 
 The match statement is used for pattern matching.  Syntax:
 
-   **match_stmt**:   'match' "subject_expr" ":" NEWLINE INDENT "case_block"+ 
DEDENT
-   **subject_expr**: "star_named_expression" "," "star_named_expressions"?
-                 | "named_expression"
-   **case_block**:   'case' "patterns" ["guard"] ":" "block"
+   match_stmt:   'match' subject_expr ":" NEWLINE INDENT case_block+ DEDENT
+   subject_expr: star_named_expression "," star_named_expressions?
+                 | named_expression
+   case_block:   'case' patterns [guard] ":" block
 
 Note:
 
@@ -2187,7 +2185,7 @@ class attributes; they are shared by instances.  Instance 
attributes
 Guards
 ------
 
-   **guard**: "if" "named_expression"
+   guard: "if" named_expression
 
 A "guard" (which is part of the "case") must succeed for code inside
 the "case" block to execute.  It takes the form: "if" followed by an
@@ -2254,16 +2252,16 @@ class attributes; they are shared by instances.  
Instance attributes
 
 The top-level syntax for "patterns" is:
 
-   **patterns**:       "open_sequence_pattern" | "pattern"
-   **pattern**:        "as_pattern" | "or_pattern"
-   **closed_pattern**: | "literal_pattern"
-                   | "capture_pattern"
-                   | "wildcard_pattern"
-                   | "value_pattern"
-                   | "group_pattern"
-                   | "sequence_pattern"
-                   | "mapping_pattern"
-                   | "class_pattern"
+   patterns:       open_sequence_pattern | pattern
+   pattern:        as_pattern | or_pattern
+   closed_pattern: | literal_pattern
+                   | capture_pattern
+                   | wildcard_pattern
+                   | value_pattern
+                   | group_pattern
+                   | sequence_pattern
+                   | mapping_pattern
+                   | class_pattern
 
 The descriptions below will include a description “in simple terms” of
 what a pattern does for illustration purposes (credits to Raymond
@@ -2279,7 +2277,7 @@ class attributes; they are shared by instances.  Instance 
attributes
 An OR pattern is two or more patterns separated by vertical bars "|".
 Syntax:
 
-   **or_pattern**: "|"."closed_pattern"+
+   or_pattern: "|".closed_pattern+
 
 Only the final subpattern may be irrefutable, and each subpattern must
 bind the same set of names to avoid ambiguity.
@@ -2300,7 +2298,7 @@ class attributes; they are shared by instances.  Instance 
attributes
 An AS pattern matches an OR pattern on the left of the "as" keyword
 against a subject.  Syntax:
 
-   **as_pattern**: "or_pattern" "as" "capture_pattern"
+   as_pattern: or_pattern "as" capture_pattern
 
 If the OR pattern fails, the AS pattern fails.  Otherwise, the AS
 pattern binds the subject to the name on the right of the as keyword
@@ -2315,14 +2313,14 @@ class attributes; they are shared by instances.  
Instance attributes
 
 A literal pattern corresponds to most literals in Python.  Syntax:
 
-   **literal_pattern**: "signed_number"
-                    | "signed_number" "+" NUMBER
-                    | "signed_number" "-" NUMBER
-                    | "strings"
+   literal_pattern: signed_number
+                    | signed_number "+" NUMBER
+                    | signed_number "-" NUMBER
+                    | strings
                     | "None"
                     | "True"
                     | "False"
-   **signed_number**:   ["-"] NUMBER
+   signed_number:   ["-"] NUMBER
 
 The rule "strings" and the token "NUMBER" are defined in the standard
 Python grammar.  Triple-quoted strings are supported.  Raw strings and
@@ -2342,7 +2340,7 @@ class attributes; they are shared by instances.  Instance 
attributes
 
 A capture pattern binds the subject value to a name. Syntax:
 
-   **capture_pattern**: !'_' NAME
+   capture_pattern: !'_' NAME
 
 A single underscore "_" is not a capture pattern (this is what "!'_'"
 expresses). It is instead treated as a "wildcard_pattern".
@@ -2365,7 +2363,7 @@ class attributes; they are shared by instances.  Instance 
attributes
 A wildcard pattern always succeeds (matches anything) and binds no
 name.  Syntax:
 
-   **wildcard_pattern**: '_'
+   wildcard_pattern: '_'
 
 "_" is a soft keyword within any pattern, but only within patterns.
 It is an identifier, as usual, even within "match" subject
@@ -2379,9 +2377,9 @@ class attributes; they are shared by instances.  Instance 
attributes
 
 A value pattern represents a named value in Python. Syntax:
 
-   **value_pattern**: "attr"
-   **attr**:          "name_or_attr" "." NAME
-   **name_or_attr**:  "attr" | NAME
+   value_pattern: attr
+   attr:          name_or_attr "." NAME
+   name_or_attr:  attr | NAME
 
 The dotted name in the pattern is looked up using standard Python name
 resolution rules.  The pattern succeeds if the value found compares
@@ -2405,7 +2403,7 @@ class attributes; they are shared by instances.  Instance 
attributes
 emphasize the intended grouping.  Otherwise, it has no additional
 syntax. Syntax:
 
-   **group_pattern**: "(" "pattern" ")"
+   group_pattern: "(" pattern ")"
 
 In simple terms "(P)" has the same effect as "P".
 
@@ -2417,12 +2415,12 @@ class attributes; they are shared by instances.  
Instance attributes
 sequence elements. The syntax is similar to the unpacking of a list or
 tuple.
 
-   **sequence_pattern**:       "[" ["maybe_sequence_pattern"] "]"
-                           | "(" ["open_sequence_pattern"] ")"
-   **open_sequence_pattern**:  "maybe_star_pattern" "," 
["maybe_sequence_pattern"]
-   **maybe_sequence_pattern**: ","."maybe_star_pattern"+ ","?
-   **maybe_star_pattern**:     "star_pattern" | "pattern"
-   **star_pattern**:           "*" ("capture_pattern" | "wildcard_pattern")
+   sequence_pattern:       "[" [maybe_sequence_pattern] "]"
+                           | "(" [open_sequence_pattern] ")"
+   open_sequence_pattern:  maybe_star_pattern "," [maybe_sequence_pattern]
+   maybe_sequence_pattern: ",".maybe_star_pattern+ ","?
+   maybe_star_pattern:     star_pattern | pattern
+   star_pattern:           "*" (capture_pattern | wildcard_pattern)
 
 There is no difference if parentheses  or square brackets are used for
 sequence patterns (i.e. "(...)" vs "[...]" ).
@@ -2505,11 +2503,11 @@ class attributes; they are shared by instances.  
Instance attributes
 A mapping pattern contains one or more key-value patterns.  The syntax
 is similar to the construction of a dictionary. Syntax:
 
-   **mapping_pattern**:     "{" ["items_pattern"] "}"
-   **items_pattern**:       ","."key_value_pattern"+ ","?
-   **key_value_pattern**:   ("literal_pattern" | "value_pattern") ":" "pattern"
-                        | "double_star_pattern"
-   **double_star_pattern**: "**" "capture_pattern"
+   mapping_pattern:     "{" [items_pattern] "}"
+   items_pattern:       ",".key_value_pattern+ ","?
+   key_value_pattern:   (literal_pattern | value_pattern) ":" pattern
+                        | double_star_pattern
+   double_star_pattern: "**" capture_pattern
 
 At most one double star pattern may be in a mapping pattern.  The
 double star pattern must be the last subpattern in the mapping
@@ -2558,12 +2556,12 @@ class attributes; they are shared by instances.  
Instance attributes
 A class pattern represents a class and its positional and keyword
 arguments (if any).  Syntax:
 
-   **class_pattern**:       "name_or_attr" "(" ["pattern_arguments" ","?] ")"
-   **pattern_arguments**:   "positional_patterns" ["," "keyword_patterns"]
-                        | "keyword_patterns"
-   **positional_patterns**: ","."pattern"+
-   **keyword_patterns**:    ","."keyword_pattern"+
-   **keyword_pattern**:     NAME "=" "pattern"
+   class_pattern:       name_or_attr "(" [pattern_arguments ","?] ")"
+   pattern_arguments:   positional_patterns ["," keyword_patterns]
+                        | keyword_patterns
+   positional_patterns: ",".pattern+
+   keyword_patterns:    ",".keyword_pattern+
+   keyword_pattern:     NAME "=" pattern
 
 The same keyword should not be repeated in class patterns.
 
@@ -2690,22 +2688,22 @@ class attributes; they are shared by instances.  
Instance attributes
 A function definition defines a user-defined function object (see
 section The standard type hierarchy):
 
-   **funcdef**:                   ["decorators"] "def" "funcname" 
["type_params"] "(" ["parameter_list"] ")"
-                              ["->" "expression"] ":" "suite"
-   **decorators**:                "decorator"+
-   **decorator**:                 "@" "assignment_expression" NEWLINE
-   **parameter_list**:            "defparameter" ("," "defparameter")* "," "/" 
["," ["parameter_list_no_posonly"]]
-                                | "parameter_list_no_posonly"
-   **parameter_list_no_posonly**: "defparameter" ("," "defparameter")* ["," 
["parameter_list_starargs"]]
-                              | "parameter_list_starargs"
-   **parameter_list_starargs**:   "*" ["star_parameter"] ("," "defparameter")* 
["," ["parameter_star_kwargs"]]
-                              "*" ("," "defparameter")+ ["," 
["parameter_star_kwargs"]]
-                              | "parameter_star_kwargs"
-   **parameter_star_kwargs**:     "**" "parameter" [","]
-   **parameter**:                 "identifier" [":" "expression"]
-   **star_parameter**:            "identifier" [":" ["*"] "expression"]
-   **defparameter**:              "parameter" ["=" "expression"]
-   **funcname**:                  "identifier"
+   funcdef:                   [decorators] "def" funcname [type_params] "(" 
[parameter_list] ")"
+                              ["->" expression] ":" suite
+   decorators:                decorator+
+   decorator:                 "@" assignment_expression NEWLINE
+   parameter_list:            defparameter ("," defparameter)* "," "/" ["," 
[parameter_list_no_posonly]]
+                                | parameter_list_no_posonly
+   parameter_list_no_posonly: defparameter ("," defparameter)* ["," 
[parameter_list_starargs]]
+                              | parameter_list_starargs
+   parameter_list_starargs:   "*" [star_parameter] ("," defparameter)* ["," 
[parameter_star_kwargs]]
+                              "*" ("," defparameter)+ ["," 
[parameter_star_kwargs]]
+                              | parameter_star_kwargs
+   parameter_star_kwargs:     "**" parameter [","]
+   parameter:                 identifier [":" expression]
+   star_parameter:            identifier [":" ["*"] expression]
+   defparameter:              parameter ["=" expression]
+   funcname:                  identifier
 
 A function definition is an executable statement.  Its execution binds
 the function name in the current local namespace to a function object
@@ -2845,9 +2843,9 @@ def whats_on_the_telly(penguin=None):
 A class definition defines a class object (see section The standard
 type hierarchy):
 
-   **classdef**:    ["decorators"] "class" "classname" ["type_params"] 
["inheritance"] ":" "suite"
-   **inheritance**: "(" ["argument_list"] ")"
-   **classname**:   "identifier"
+   classdef:    [decorators] "class" classname [type_params] [inheritance] ":" 
suite
+   inheritance: "(" [argument_list] ")"
+   classname:   identifier
 
 A class definition is an executable statement.  The inheritance list
 usually gives a list of base classes (see Metaclasses for more
@@ -2937,8 +2935,8 @@ class attributes; they are shared by instances.  Instance 
attributes
 Coroutine function definition
 -----------------------------
 
-   **async_funcdef**: ["decorators"] "async" "def" "funcname" "(" 
["parameter_list"] ")"
-                  ["->" "expression"] ":" "suite"
+   async_funcdef: [decorators] "async" "def" funcname "(" [parameter_list] ")"
+                  ["->" expression] ":" suite
 
 Execution of Python coroutines can be suspended and resumed at many
 points (see *coroutine*). "await" expressions, "async for" and "async
@@ -2964,7 +2962,7 @@ async def func(param1, param2):
 The "async for" statement
 -------------------------
 
-   **async_for_stmt**: "async" "for_stmt"
+   async_for_stmt: "async" for_stmt
 
 An *asynchronous iterable* provides an "__aiter__" method that
 directly returns an *asynchronous iterator*, which can call
@@ -3005,7 +3003,7 @@ async def func(param1, param2):
 The "async with" statement
 --------------------------
 
-   **async_with_stmt**: "async" "with_stmt"
+   async_with_stmt: "async" with_stmt
 
 An *asynchronous context manager* is a *context manager* that is able
 to suspend execution in its *enter* and *exit* methods.
@@ -3054,11 +3052,11 @@ async def func(param1, param2):
 Changed in version 3.13: Support for default values was added (see
 **PEP 696**).
 
-   **type_params**:  "[" "type_param" ("," "type_param")* "]"
-   **type_param**:   "typevar" | "typevartuple" | "paramspec"
-   **typevar**:      "identifier" (":" "expression")? ("=" "expression")?
-   **typevartuple**: "*" "identifier" ("=" "expression")?
-   **paramspec**:    "**" "identifier" ("=" "expression")?
+   type_params:  "[" type_param ("," type_param)* "]"
+   type_param:   typevar | typevartuple | paramspec
+   typevar:      identifier (":" expression)? ("=" expression)?
+   typevartuple: "*" identifier ("=" expression)?
+   paramspec:    "**" identifier ("=" expression)?
 
 Functions (including coroutines), classes and type aliases may contain
 a type parameter list:
@@ -3424,7 +3422,7 @@ def f() -> annotation: ...
     'continue': r'''The "continue" statement
 ************************
 
-   **continue_stmt**: "continue"
+   continue_stmt: "continue"
 
 "continue" may only occur syntactically nested in a "for" or "while"
 loop, but not nested in a function or class definition within that
@@ -3942,11 +3940,31 @@ def double(x):
    Enter post-mortem debugging of the exception found in
    "sys.last_exc".
 
+pdb.set_default_backend(backend)
+
+   There are two supported backends for pdb: "'settrace'" and
+   "'monitoring'". See "bdb.Bdb" for details. The user can set the
+   default backend to use if none is specified when instantiating
+   "Pdb". If no backend is specified, the default is "'settrace'".
+
+   Note:
+
+     "breakpoint()" and "set_trace()" will not be affected by this
+     function. They always use "'monitoring'" backend.
+
+   Added in version 3.14.
+
+pdb.get_default_backend()
+
+   Returns the default backend for pdb.
+
+   Added in version 3.14.
+
 The "run*" functions and "set_trace()" are aliases for instantiating
 the "Pdb" class and calling the method of the same name.  If you want
 to access further features, you have to do this yourself:
 
-class pdb.Pdb(completekey='tab', stdin=None, stdout=None, skip=None, 
nosigint=False, readrc=True, mode=None)
+class pdb.Pdb(completekey='tab', stdin=None, stdout=None, skip=None, 
nosigint=False, readrc=True, mode=None, backend=None)
 
    "Pdb" is the debugger class.
 
@@ -3972,6 +3990,11 @@ class pdb.Pdb(completekey='tab', stdin=None, 
stdout=None, skip=None, nosigint=Fa
    command line invocation) or "None" (for backwards compatible
    behaviour, as before the *mode* argument was added).
 
+   The *backend* argument specifies the backend to use for the
+   debugger. If "None" is passed, the default backend will be used.
+   See "set_default_backend()". Otherwise the supported backends are
+   "'settrace'" and "'monitoring'".
+
    Example call to enable tracing with *skip*:
 
       import pdb; pdb.Pdb(skip=['django.*']).set_trace()
@@ -3987,6 +4010,8 @@ class pdb.Pdb(completekey='tab', stdin=None, stdout=None, 
skip=None, nosigint=Fa
 
    Added in version 3.14: Added the *mode* argument.
 
+   Added in version 3.14: Added the *backend* argument.
+
    Changed in version 3.14: Inline breakpoints like "breakpoint()" or
    "pdb.set_trace()" will always stop the program at calling frame,
    ignoring the *skip* pattern (if any).
@@ -4045,7 +4070,7 @@ class pdb.Pdb(completekey='tab', stdin=None, stdout=None, 
skip=None, nosigint=Fa
 the program resumes execution so it’s less likely to interfere with
 your program compared to using normal variables like "foo = 1".
 
-There are three preset *convenience variables*:
+There are four preset *convenience variables*:
 
 * "$_frame": the current frame you are debugging
 
@@ -4053,8 +4078,12 @@ class pdb.Pdb(completekey='tab', stdin=None, 
stdout=None, skip=None, nosigint=Fa
 
 * "$_exception": the exception if the frame is raising an exception
 
+* "$_asynctask": the asyncio task if pdb stops in an async function
+
 Added in version 3.12: Added the *convenience variable* feature.
 
+Added in version 3.14: Added the "$_asynctask" convenience variable.
+
 If a file ".pdbrc" exists in the user’s home directory or in the
 current directory, it is read with "'utf-8'" encoding and executed as
 if it had been typed at the debugger prompt, with the exception that
@@ -4510,7 +4539,7 @@ def inner(x):
     'del': r'''The "del" statement
 *******************
 
-   **del_stmt**: "del" "target_list"
+   del_stmt: "del" target_list
 
 Deletion is recursively defined very similar to the way assignment is
 defined. Rather than spelling it out in full details, here are some
@@ -4539,10 +4568,10 @@ def inner(x):
 A dictionary display is a possibly empty series of dict items
 (key/value pairs) enclosed in curly braces:
 
-   **dict_display**:       "{" ["dict_item_list" | "dict_comprehension"] "}"
-   **dict_item_list**:     "dict_item" ("," "dict_item")* [","]
-   **dict_item**:          "expression" ":" "expression" | "**" "or_expr"
-   **dict_comprehension**: "expression" ":" "expression" "comp_for"
+   dict_display:       "{" [dict_item_list | dict_comprehension] "}"
+   dict_item_list:     dict_item ("," dict_item)* [","]
+   dict_item:          expression ":" expression | "**" or_expr
+   dict_comprehension: expression ":" expression comp_for
 
 A dictionary display yields a new dictionary object.
 
@@ -4603,9 +4632,9 @@ def f():
 
 The "if" statement is used for conditional execution:
 
-   **if_stmt**: "if" "assignment_expression" ":" "suite"
-            ("elif" "assignment_expression" ":" "suite")*
-            ["else" ":" "suite"]
+   if_stmt: "if" assignment_expression ":" suite
+            ("elif" assignment_expression ":" suite)*
+            ["else" ":" suite]
 
 It selects exactly one of the suites by evaluating the expressions one
 by one until one is found to be true (see section Boolean operations
@@ -5024,12 +5053,12 @@ class of the instance or a *non-virtual base class* 
thereof. The
     'exprlists': r'''Expression lists
 ****************
 
-   **starred_expression**:       ["*"] "or_expr"
-   **flexible_expression**:      "assignment_expression" | "starred_expression"
-   **flexible_expression_list**: "flexible_expression" ("," 
"flexible_expression")* [","]
-   **starred_expression_list**:  "starred_expression" ("," 
"starred_expression")* [","]
-   **expression_list**:          "expression" ("," "expression")* [","]
-   **yield_list**:               "expression_list" | "starred_expression" "," 
["starred_expression_list"]
+   starred_expression:       ["*"] or_expr
+   flexible_expression:      assignment_expression | starred_expression
+   flexible_expression_list: flexible_expression ("," flexible_expression)* 
[","]
+   starred_expression_list:  starred_expression ("," starred_expression)* [","]
+   expression_list:          expression ("," expression)* [","]
+   yield_list:               expression_list | starred_expression "," 
[starred_expression_list]
 
 Except when part of a list or set display, an expression list
 containing at least one comma yields a tuple.  The length of the tuple
@@ -5059,12 +5088,12 @@ class of the instance or a *non-virtual base class* 
thereof. The
 Floating-point literals are described by the following lexical
 definitions:
 
-   **floatnumber**:   "pointfloat" | "exponentfloat"
-   **pointfloat**:    ["digitpart"] "fraction" | "digitpart" "."
-   **exponentfloat**: ("digitpart" | "pointfloat") "exponent"
-   **digitpart**:     "digit" (["_"] "digit")*
-   **fraction**:      "." "digitpart"
-   **exponent**:      ("e" | "E") ["+" | "-"] "digitpart"
+   floatnumber:   pointfloat | exponentfloat
+   pointfloat:    [digitpart] fraction | digitpart "."
+   exponentfloat: (digitpart | pointfloat) exponent
+   digitpart:     digit (["_"] digit)*
+   fraction:      "." digitpart
+   exponent:      ("e" | "E") ["+" | "-"] digitpart
 
 Note that the integer and exponent parts are always interpreted using
 radix 10. For example, "077e010" is legal, and denotes the same number
@@ -5085,8 +5114,8 @@ class of the instance or a *non-virtual base class* 
thereof. The
 The "for" statement is used to iterate over the elements of a sequence
 (such as a string, tuple or list) or other iterable object:
 
-   **for_stmt**: "for" "target_list" "in" "starred_list" ":" "suite"
-             ["else" ":" "suite"]
+   for_stmt: "for" target_list "in" starred_list ":" suite
+             ["else" ":" suite]
 
 The "starred_list" expression is evaluated once; it should yield an
 *iterable* object.  An *iterator* is created for that iterable. The
@@ -5140,14 +5169,14 @@ class of the instance or a *non-virtual base class* 
thereof. The
 
 The grammar for a replacement field is as follows:
 
-   **replacement_field**: "{" ["field_name"] ["!" "conversion"] [":" 
"format_spec"] "}"
-   **field_name**:        "arg_name" ("." "attribute_name" | "[" 
"element_index" "]")*
-   **arg_name**:          ["identifier" | "digit"+]
-   **attribute_name**:    "identifier"
-   **element_index**:     "digit"+ | "index_string"
-   **index_string**:      <any source character except "]"> +
-   **conversion**:        "r" | "s" | "a"
-   **format_spec**:       "format-spec:format_spec"
+   replacement_field: "{" [field_name] ["!" conversion] [":" format_spec] "}"
+   field_name:        arg_name ("." attribute_name | "[" element_index "]")*
+   arg_name:          [identifier | digit+]
+   attribute_name:    identifier
+   element_index:     digit+ | index_string
+   index_string:      <any source character except "]"> +
+   conversion:        "r" | "s" | "a"
+   format_spec:       format-spec:format_spec
 
 In less formal terms, the replacement field can start with a
 *field_name* that specifies the object whose value is to be formatted
@@ -5244,18 +5273,18 @@ class of the instance or a *non-virtual base class* 
thereof. The
 
 The general form of a *standard format specifier* is:
 
-   **format_spec**:             ["options"]["width_and_precision"]["type"]
-   **options**:                 [["fill"]"align"]["sign"]["z"]["#"]["0"]
-   **fill**:                    <any character>
-   **align**:                   "<" | ">" | "=" | "^"
-   **sign**:                    "+" | "-" | " "
-   **width_and_precision**:     
["width_with_grouping"]["precision_with_grouping"]
-   **width_with_grouping**:     ["width"]["grouping_option"]
-   **precision_with_grouping**: "." ["precision"]"grouping_option"
-   **width**:                   "digit"+
-   **grouping_option**:         "_" | ","
-   **precision**:               "digit"+
-   **type**:                    "b" | "c" | "d" | "e" | "E" | "f" | "F" | "g"
+   format_spec:             [options][width_and_precision][type]
+   options:                 [[fill]align][sign]["z"]["#"]["0"]
+   fill:                    <any character>
+   align:                   "<" | ">" | "=" | "^"
+   sign:                    "+" | "-" | " "
+   width_and_precision:     [width_with_grouping][precision_with_grouping]
+   width_with_grouping:     [width][grouping_option]
+   precision_with_grouping: "." [precision]grouping_option
+   width:                   digit+
+   grouping_option:         "_" | ","
+   precision:               digit+
+   type:                    "b" | "c" | "d" | "e" | "E" | "f" | "F" | "g"
                             | "G" | "n" | "o" | "s" | "x" | "X" | "%"
 
 If a valid *align* value is specified, it can be preceded by a *fill*
@@ -5665,22 +5694,22 @@ class of the instance or a *non-virtual base class* 
thereof. The
 A function definition defines a user-defined function object (see
 section The standard type hierarchy):
 
-   **funcdef**:                   ["decorators"] "def" "funcname" 
["type_params"] "(" ["parameter_list"] ")"
-                              ["->" "expression"] ":" "suite"
-   **decorators**:                "decorator"+
-   **decorator**:                 "@" "assignment_expression" NEWLINE
-   **parameter_list**:            "defparameter" ("," "defparameter")* "," "/" 
["," ["parameter_list_no_posonly"]]
-                                | "parameter_list_no_posonly"
-   **parameter_list_no_posonly**: "defparameter" ("," "defparameter")* ["," 
["parameter_list_starargs"]]
-                              | "parameter_list_starargs"
-   **parameter_list_starargs**:   "*" ["star_parameter"] ("," "defparameter")* 
["," ["parameter_star_kwargs"]]
-                              "*" ("," "defparameter")+ ["," 
["parameter_star_kwargs"]]
-                              | "parameter_star_kwargs"
-   **parameter_star_kwargs**:     "**" "parameter" [","]
-   **parameter**:                 "identifier" [":" "expression"]
-   **star_parameter**:            "identifier" [":" ["*"] "expression"]
-   **defparameter**:              "parameter" ["=" "expression"]
-   **funcname**:                  "identifier"
+   funcdef:                   [decorators] "def" funcname [type_params] "(" 
[parameter_list] ")"
+                              ["->" expression] ":" suite
+   decorators:                decorator+
+   decorator:                 "@" assignment_expression NEWLINE
+   parameter_list:            defparameter ("," defparameter)* "," "/" ["," 
[parameter_list_no_posonly]]
+                                | parameter_list_no_posonly
+   parameter_list_no_posonly: defparameter ("," defparameter)* ["," 
[parameter_list_starargs]]
+                              | parameter_list_starargs
+   parameter_list_starargs:   "*" [star_parameter] ("," defparameter)* ["," 
[parameter_star_kwargs]]
+                              "*" ("," defparameter)+ ["," 
[parameter_star_kwargs]]
+                              | parameter_star_kwargs
+   parameter_star_kwargs:     "**" parameter [","]
+   parameter:                 identifier [":" expression]
+   star_parameter:            identifier [":" ["*"] expression]
+   defparameter:              parameter ["=" expression]
+   funcname:                  identifier
 
 A function definition is an executable statement.  Its execution binds
 the function name in the current local namespace to a function object
@@ -5816,7 +5845,7 @@ def whats_on_the_telly(penguin=None):
     'global': r'''The "global" statement
 **********************
 
-   **global_stmt**: "global" "identifier" ("," "identifier")*
+   global_stmt: "global" identifier ("," identifier)*
 
 The "global" statement causes the listed identifiers to be interpreted
 as globals. It would be impossible to assign to a global variable
@@ -5899,11 +5928,11 @@ class body. A "SyntaxError" is raised if a variable is 
used or
 
 Identifiers are unlimited in length.  Case is significant.
 
-   **identifier**:   "xid_start" "xid_continue"*
-   **id_start**:     <all characters in general categories Lu, Ll, Lt, Lm, Lo, 
Nl, the underscore, and characters with the Other_ID_Start property>
-   **id_continue**:  <all characters in "id_start", plus characters in the 
categories Mn, Mc, Nd, Pc and others with the Other_ID_Continue property>
-   **xid_start**:    <all characters in "id_start" whose NFKC normalization is 
in "id_start xid_continue*">
-   **xid_continue**: <all characters in "id_continue" whose NFKC normalization 
is in "id_continue*">
+   identifier:   xid_start xid_continue*
+   id_start:     <all characters in general categories Lu, Ll, Lt, Lm, Lo, Nl, 
the underscore, and characters with the Other_ID_Start property>
+   id_continue:  <all characters in id_start, plus characters in the 
categories Mn, Mc, Nd, Pc and others with the Other_ID_Continue property>
+   xid_start:    <all characters in id_start whose NFKC normalization is in 
"id_start xid_continue*">
+   xid_continue: <all characters in id_continue whose NFKC normalization is in 
"id_continue*">
 
 The Unicode category codes mentioned above stand for:
 
@@ -6024,9 +6053,9 @@ class body. A "SyntaxError" is raised if a variable is 
used or
 
 The "if" statement is used for conditional execution:
 
-   **if_stmt**: "if" "assignment_expression" ":" "suite"
-            ("elif" "assignment_expression" ":" "suite")*
-            ["else" ":" "suite"]
+   if_stmt: "if" assignment_expression ":" suite
+            ("elif" assignment_expression ":" suite)*
+            ["else" ":" suite]
 
 It selects exactly one of the suites by evaluating the expressions one
 by one until one is found to be true (see section Boolean operations
@@ -6040,7 +6069,7 @@ class body. A "SyntaxError" is raised if a variable is 
used or
 
 Imaginary literals are described by the following lexical definitions:
 
-   **imagnumber**: ("floatnumber" | "digitpart") ("j" | "J")
+   imagnumber: (floatnumber | digitpart) ("j" | "J")
 
 An imaginary literal yields a complex number with a real part of 0.0.
 Complex numbers are represented as a pair of floating-point numbers
@@ -6053,14 +6082,14 @@ class body. A "SyntaxError" is raised if a variable is 
used or
     'import': r'''The "import" statement
 **********************
 
-   **import_stmt**:     "import" "module" ["as" "identifier"] ("," "module" 
["as" "identifier"])*
-                    | "from" "relative_module" "import" "identifier" ["as" 
"identifier"]
-                    ("," "identifier" ["as" "identifier"])*
-                    | "from" "relative_module" "import" "(" "identifier" ["as" 
"identifier"]
-                    ("," "identifier" ["as" "identifier"])* [","] ")"
-                    | "from" "relative_module" "import" "*"
-   **module**:          ("identifier" ".")* "identifier"
-   **relative_module**: "."* "module" | "."+
+   import_stmt:     "import" module ["as" identifier] ("," module ["as" 
identifier])*
+                    | "from" relative_module "import" identifier ["as" 
identifier]
+                    ("," identifier ["as" identifier])*
+                    | "from" relative_module "import" "(" identifier ["as" 
identifier]
+                    ("," identifier ["as" identifier])* [","] ")"
+                    | "from" relative_module "import" "*"
+   module:          (identifier ".")* identifier
+   relative_module: "."* module | "."+
 
 The basic import statement (no "from" clause) is executed in two
 steps:
@@ -6179,11 +6208,11 @@ class body. A "SyntaxError" is raised if a variable is 
used or
 allows use of the new features on a per-module basis before the
 release in which the feature becomes standard.
 
-   **future_stmt**: "from" "__future__" "import" "feature" ["as" "identifier"]
-                ("," "feature" ["as" "identifier"])*
-                | "from" "__future__" "import" "(" "feature" ["as" 
"identifier"]
-                ("," "feature" ["as" "identifier"])* [","] ")"
-   **feature**:     "identifier"
+   future_stmt: "from" "__future__" "import" feature ["as" identifier]
+                ("," feature ["as" identifier])*
+                | "from" "__future__" "import" "(" feature ["as" identifier]
+                ("," feature ["as" identifier])* [","] ")"
+   feature:     identifier
 
 A future statement must appear near the top of the module.  The only
 lines that can appear before a future statement are:
@@ -6292,16 +6321,16 @@ class body. A "SyntaxError" is raised if a variable is 
used or
 
 Integer literals are described by the following lexical definitions:
 
-   **integer**:      "decinteger" | "bininteger" | "octinteger" | "hexinteger"
-   **decinteger**:   "nonzerodigit" (["_"] "digit")* | "0"+ (["_"] "0")*
-   **bininteger**:   "0" ("b" | "B") (["_"] "bindigit")+
-   **octinteger**:   "0" ("o" | "O") (["_"] "octdigit")+
-   **hexinteger**:   "0" ("x" | "X") (["_"] "hexdigit")+
-   **nonzerodigit**: "1"..."9"
-   **digit**:        "0"..."9"
-   **bindigit**:     "0" | "1"
-   **octdigit**:     "0"..."7"
-   **hexdigit**:     "digit" | "a"..."f" | "A"..."F"
+   integer:      decinteger | bininteger | octinteger | hexinteger
+   decinteger:   nonzerodigit (["_"] digit)* | "0"+ (["_"] "0")*
+   bininteger:   "0" ("b" | "B") (["_"] bindigit)+
+   octinteger:   "0" ("o" | "O") (["_"] octdigit)+
+   hexinteger:   "0" ("x" | "X") (["_"] hexdigit)+
+   nonzerodigit: "1"..."9"
+   digit:        "0"..."9"
+   bindigit:     "0" | "1"
+   octdigit:     "0"..."7"
+   hexdigit:     digit | "a"..."f" | "A"..."F"
 
 There is no limit for the length of integer literals apart from what
 can be stored in available memory.
@@ -6327,7 +6356,7 @@ class body. A "SyntaxError" is raised if a variable is 
used or
     'lambda': r'''Lambdas
 *******
 
-   **lambda_expr**: "lambda" ["parameter_list"] ":" "expression"
+   lambda_expr: "lambda" [parameter_list] ":" expression
 
 Lambda expressions (sometimes called lambda forms) are used to create
 anonymous functions. The expression "lambda parameters: expression"
@@ -6347,7 +6376,7 @@ def <lambda>(parameters):
 A list display is a possibly empty series of expressions enclosed in
 square brackets:
 
-   **list_display**: "[" ["flexible_expression_list" | "comprehension"] "]"
+   list_display: "[" [flexible_expression_list | comprehension] "]"
 
 A list display yields a new list object, the contents being specified
 by either a list of expressions or a comprehension.  When a comma-
@@ -6640,7 +6669,7 @@ def f():
     'nonlocal': r'''The "nonlocal" statement
 ************************
 
-   **nonlocal_stmt**: "nonlocal" "identifier" ("," "identifier")*
+   nonlocal_stmt: "nonlocal" identifier ("," identifier)*
 
 When the definition of a function or class is nested (enclosed) within
 the definitions of other functions, its nonlocal scopes are the local
@@ -7027,7 +7056,7 @@ class that has an "__rsub__()" method, 
"type(y).__rsub__(y, x)" is
     'pass': r'''The "pass" statement
 ********************
 
-   **pass_stmt**: "pass"
+   pass_stmt: "pass"
 
 "pass" is a null operation — when it is executed, nothing happens. It
 is useful as a placeholder when a statement is required syntactically,
@@ -7044,7 +7073,7 @@ class C: pass       # a class with no methods (yet)
 left; it binds less tightly than unary operators on its right.  The
 syntax is:
 
-   **power**: ("await_expr" | "primary") ["**" "u_expr"]
+   power: (await_expr | primary) ["**" u_expr]
 
 Thus, in an unparenthesized sequence of power and unary operators, the
 operators are evaluated from right to left (this does not constrain
@@ -7070,7 +7099,7 @@ class C: pass       # a class with no methods (yet)
     'raise': r'''The "raise" statement
 *********************
 
-   **raise_stmt**: "raise" ["expression" ["from" "expression"]]
+   raise_stmt: "raise" [expression ["from" expression]]
 
 If no expressions are present, "raise" re-raises the exception that is
 currently being handled, which is also known as the *active
@@ -7172,7 +7201,7 @@ class C: pass       # a class with no methods (yet)
     'return': r'''The "return" statement
 **********************
 
-   **return_stmt**: "return" ["expression_list"]
+   return_stmt: "return" [expression_list]
 
 "return" may only occur syntactically nested in a function definition,
 not within a nested class definition.
@@ -7357,7 +7386,7 @@ class C: pass       # a class with no methods (yet)
 The shifting operations have lower priority than the arithmetic
 operations:
 
-   **shift_expr**: "a_expr" | "shift_expr" ("<<" | ">>") "a_expr"
+   shift_expr: a_expr | shift_expr ("<<" | ">>") a_expr
 
 These operators accept integers as arguments.  They shift the first
 argument to the left or right by the number of bits given by the
@@ -7378,13 +7407,13 @@ class C: pass       # a class with no methods (yet)
 string, tuple or list).  Slicings may be used as expressions or as
 targets in assignment or "del" statements.  The syntax for a slicing:
 
-   **slicing**:      "primary" "[" "slice_list" "]"
-   **slice_list**:   "slice_item" ("," "slice_item")* [","]
-   **slice_item**:   "expression" | "proper_slice"
-   **proper_slice**: ["lower_bound"] ":" ["upper_bound"] [ ":" ["stride"] ]
-   **lower_bound**:  "expression"
-   **upper_bound**:  "expression"
-   **stride**:       "expression"
+   slicing:      primary "[" slice_list "]"
+   slice_list:   slice_item ("," slice_item)* [","]
+   slice_item:   expression | proper_slice
+   proper_slice: [lower_bound] ":" [upper_bound] [ ":" [stride] ]
+   lower_bound:  expression
+   upper_bound:  expression
+   stride:       expression
 
 There is ambiguity in the formal syntax here: anything that looks like
 an expression list also looks like a slice list, so any subscription
@@ -9776,26 +9805,26 @@ class is used in a class pattern with positional 
arguments, each
 
 String literals are described by the following lexical definitions:
 
-   **stringliteral**:   ["stringprefix"]("shortstring" | "longstring")
-   **stringprefix**:    "r" | "u" | "R" | "U" | "f" | "F"
+   stringliteral:   [stringprefix](shortstring | longstring)
+   stringprefix:    "r" | "u" | "R" | "U" | "f" | "F"
                     | "fr" | "Fr" | "fR" | "FR" | "rf" | "rF" | "Rf" | "RF"
-   **shortstring**:     "'" "shortstringitem"* "'" | '"' "shortstringitem"* '"'
-   **longstring**:      "\'\'\'" "longstringitem"* "\'\'\'" | '"""' 
"longstringitem"* '"""'
-   **shortstringitem**: "shortstringchar" | "stringescapeseq"
-   **longstringitem**:  "longstringchar" | "stringescapeseq"
-   **shortstringchar**: <any source character except "\\" or newline or the 
quote>
-   **longstringchar**:  <any source character except "\\">
-   **stringescapeseq**: "\\" <any source character>
-
-   **bytesliteral**:   "bytesprefix"("shortbytes" | "longbytes")
-   **bytesprefix**:    "b" | "B" | "br" | "Br" | "bR" | "BR" | "rb" | "rB" | 
"Rb" | "RB"
-   **shortbytes**:     "'" "shortbytesitem"* "'" | '"' "shortbytesitem"* '"'
-   **longbytes**:      "\'\'\'" "longbytesitem"* "\'\'\'" | '"""' 
"longbytesitem"* '"""'
-   **shortbytesitem**: "shortbyteschar" | "bytesescapeseq"
-   **longbytesitem**:  "longbyteschar" | "bytesescapeseq"
-   **shortbyteschar**: <any ASCII character except "\\" or newline or the 
quote>
-   **longbyteschar**:  <any ASCII character except "\\">
-   **bytesescapeseq**: "\\" <any ASCII character>
+   shortstring:     "'" shortstringitem* "'" | '"' shortstringitem* '"'
+   longstring:      "\'\'\'" longstringitem* "\'\'\'" | '"""' longstringitem* 
'"""'
+   shortstringitem: shortstringchar | stringescapeseq
+   longstringitem:  longstringchar | stringescapeseq
+   shortstringchar: <any source character except "\\" or newline or the quote>
+   longstringchar:  <any source character except "\\">
+   stringescapeseq: "\\" <any source character>
+
+   bytesliteral:   bytesprefix(shortbytes | longbytes)
+   bytesprefix:    "b" | "B" | "br" | "Br" | "bR" | "BR" | "rb" | "rB" | "Rb" 
| "RB"
+   shortbytes:     "'" shortbytesitem* "'" | '"' shortbytesitem* '"'
+   longbytes:      "\'\'\'" longbytesitem* "\'\'\'" | '"""' longbytesitem* 
'"""'
+   shortbytesitem: shortbyteschar | bytesescapeseq
+   longbytesitem:  longbyteschar | bytesescapeseq
+   shortbyteschar: <any ASCII character except "\\" or newline or the quote>
+   longbyteschar:  <any ASCII character except "\\">
+   bytesescapeseq: "\\" <any ASCII character>
 
 One syntactic restriction not indicated by these productions is that
 whitespace is not allowed between the "stringprefix" or "bytesprefix"
@@ -9959,7 +9988,7 @@ class is used in a class pattern with positional 
arguments, each
 select an element from the container. The subscription of a *generic
 class* will generally return a GenericAlias object.
 
-   **subscription**: "primary" "[" "flexible_expression_list" "]"
+   subscription: primary "[" flexible_expression_list "]"
 
 When an object is subscripted, the interpreter will evaluate the
 primary and the expression list.
@@ -10039,17 +10068,17 @@ class is used in a class pattern with positional 
arguments, each
 The "try" statement specifies exception handlers and/or cleanup code
 for a group of statements:
 
-   **try_stmt**:  "try1_stmt" | "try2_stmt" | "try3_stmt"
-   **try1_stmt**: "try" ":" "suite"
-              ("except" ["expression" ["as" "identifier"]] ":" "suite")+
-              ["else" ":" "suite"]
-              ["finally" ":" "suite"]
-   **try2_stmt**: "try" ":" "suite"
-              ("except" "*" "expression" ["as" "identifier"] ":" "suite")+
-              ["else" ":" "suite"]
-              ["finally" ":" "suite"]
-   **try3_stmt**: "try" ":" "suite"
-              "finally" ":" "suite"
+   try_stmt:  try1_stmt | try2_stmt | try3_stmt
+   try1_stmt: "try" ":" suite
+              ("except" [expression ["as" identifier]] ":" suite)+
+              ["else" ":" suite]
+              ["finally" ":" suite]
+   try2_stmt: "try" ":" suite
+              ("except" "*" expression ["as" identifier] ":" suite)+
+              ["else" ":" suite]
+              ["finally" ":" suite]
+   try3_stmt: "try" ":" suite
+              "finally" ":" suite
 
 Additional information on exceptions can be found in section
 Exceptions, and information on using the "raise" statement to generate
@@ -10211,16 +10240,13 @@ class is used in a class pattern with positional 
arguments, each
 clause.  If the "finally" clause raises another exception, the saved
 exception is set as the context of the new exception. If the "finally"
 clause executes a "return", "break" or "continue" statement, the saved
-exception is discarded:
+exception is discarded. For example, this function returns 42.
 
-   >>> def f():
-   ...     try:
-   ...         1/0
-   ...     finally:
-   ...         return 42
-   ...
-   >>> f()
-   42
+   def f():
+       try:
+           1/0
+       finally:
+           return 42
 
 The exception information is not available to the program during
 execution of the "finally" clause.
@@ -10232,20 +10258,21 @@ class is used in a class pattern with positional 
arguments, each
 The return value of a function is determined by the last "return"
 statement executed.  Since the "finally" clause always executes, a
 "return" statement executed in the "finally" clause will always be the
-last one executed:
+last one executed. The following function returns ‘finally’.
 
-   >>> def foo():
-   ...     try:
-   ...         return 'try'
-   ...     finally:
-   ...         return 'finally'
-   ...
-   >>> foo()
-   'finally'
+   def foo():
+       try:
+           return 'try'
+       finally:
+           return 'finally'
 
 Changed in version 3.8: Prior to Python 3.8, a "continue" statement
 was illegal in the "finally" clause due to a problem with the
 implementation.
+
+Changed in version 3.14.0a6 (unreleased): The compiler emits a
+"SyntaxWarning" when a "return", "break" or "continue" appears in a
+"finally" block (see **PEP 765**).
 ''',
     'types': r'''The standard type hierarchy
 ***************************
@@ -12658,7 +12685,7 @@ class range(start, stop[, step])
 
 All unary arithmetic and bitwise operations have the same priority:
 
-   **u_expr**: "power" | "-" "u_expr" | "+" "u_expr" | "~" "u_expr"
+   u_expr: power | "-" u_expr | "+" u_expr | "~" u_expr
 
 The unary "-" (minus) operator yields the negation of its numeric
 argument; the operation can be overridden with the "__neg__()" special
@@ -12681,8 +12708,8 @@ class range(start, stop[, step])
 The "while" statement is used for repeated execution as long as an
 expression is true:
 
-   **while_stmt**: "while" "assignment_expression" ":" "suite"
-               ["else" ":" "suite"]
+   while_stmt: "while" assignment_expression ":" suite
+               ["else" ":" suite]
 
 This repeatedly tests the expression and, if it is true, executes the
 first suite; if the expression is false (which may be the first time
@@ -12702,9 +12729,9 @@ class range(start, stop[, step])
 Context Managers). This allows common "try"…"except"…"finally" usage
 patterns to be encapsulated for convenient reuse.
 
-   **with_stmt**:          "with" ( "(" "with_stmt_contents" ","? ")" | 
"with_stmt_contents" ) ":" "suite"
-   **with_stmt_contents**: "with_item" ("," "with_item")*
-   **with_item**:          "expression" ["as" "target"]
+   with_stmt:          "with" ( "(" with_stmt_contents ","? ")" | 
with_stmt_contents ) ":" suite
+   with_stmt_contents: with_item ("," with_item)*
+   with_item:          expression ["as" target]
 
 The execution of the "with" statement with one “item” proceeds as
 follows:
@@ -12805,7 +12832,7 @@ class range(start, stop[, step])
     'yield': r'''The "yield" statement
 *********************
 
-   **yield_stmt**: "yield_expression"
+   yield_stmt: yield_expression
 
 A "yield" statement is semantically equivalent to a yield expression.
 The "yield" statement can be used to omit the parentheses that would

_______________________________________________
Python-checkins mailing list -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: arch...@mail-archive.com

Reply via email to