From 443c0cd17c5b0c71ee45c3621777454c6b8b0cbd Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+AA-Turner@users.noreply.github.com> Date: Thu, 20 Mar 2025 15:35:20 +0000 Subject: gh-127833: Use `productionlist` nodes to implement the `grammar-snippet` directive (#130376) Co-authored-by: Petr Viktorin Co-authored-by: Blaise Pabon --- Doc/tools/extensions/grammar_snippet.py | 182 ++++---- Lib/pydoc_data/topics.py | 721 +++++++++++++++++--------------- 2 files changed, 486 insertions(+), 417 deletions(-) diff --git a/Doc/tools/extensions/grammar_snippet.py b/Doc/tools/extensions/grammar_snippet.py index 03c7e7c..1e059f1 100644 --- a/Doc/tools/extensions/grammar_snippet.py +++ b/Doc/tools/extensions/grammar_snippet.py @@ -13,8 +13,8 @@ from sphinx.util.docutils import SphinxDirective 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^[a-zA-Z0-9_]+) # identifier at start of line + (?=:) # ... followed by a colon + | + (?P`[^\s`]+`) # identifier in backquotes + | + (?P'[^']*') # string in 'quotes' + | + (?P"[^"]*") # 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^[a-zA-Z0-9_]+) # identifier at start of line - (?=:) # ... followed by a colon - | - (?P`[^\s`]+`) # identifier in backquotes - | - (?P'[^']*') # string in 'quotes' - | - (?P"[^"]*") # 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 d392efe..f949b96 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 @@ topics = { 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 @@ variable is determined when the interpreter starts. 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 @@ Augmented assignment statements 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 @@ Annotated assignment statements 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 @@ annotations are never evaluated. '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 @@ Added in version 3.5. 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 @@ coroutine function. 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 @@ of a coroutine function. 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 @@ The transformation rule is defined as follows: 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 @@ Notes on using *__slots__*: 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 @@ method, that method is called as a fallback. 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 @@ numeric types. Apart from the power operator, there are only two 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 @@ other operand is converted to a floating-point number. 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 @@ Types are written like this: "". '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 @@ argument (for example, "not 'foo'" produces "False" rather than "''".) '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 @@ object.__call__(self[, args...]) 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 @@ a class instance: 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 @@ which is lower than that of any arithmetic, shifting or bitwise 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 @@ context, so that in the following example, either all or none of the 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 @@ The "if" statement 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 @@ The "while" statement 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 @@ The "for" statement 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 @@ The "try" statement 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 @@ there is a saved exception it is re-raised at the end of the "finally" 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 @@ also executed ‘on the way out.’ 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 @@ methods defined by a context manager (see section With Statement 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 @@ Added in version 3.10. 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 @@ section. 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 @@ Note: 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 @@ OR Patterns 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 @@ AS Patterns 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 @@ Literal Patterns 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 @@ Capture Patterns 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 @@ Wildcard Patterns 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 @@ Value Patterns 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 @@ A group pattern allows users to add parentheses around patterns to 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 @@ A sequence pattern contains several subpatterns to be matched against 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 @@ Mapping Patterns 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 Patterns 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 @@ Function definitions 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 @@ Class definitions 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 @@ Added in version 3.5. 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 @@ coroutine function. 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 @@ of a coroutine function. 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 @@ Added in version 3.12. 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 @@ See also: '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 @@ pdb.pm() 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 @@ the debugger session. The *convenience variables* are cleared when 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 @@ There are three preset *convenience variables*: * "$_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 @@ exceptions [excnumber] '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 @@ block. 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 @@ specified, it is used for both. 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 @@ statement and "raise" statement in section The raise statement. '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 @@ parentheses: "()".) 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 @@ purposes in literals. 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 @@ a brace character in the literal text, it can be escaped by doubling: 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**: + - **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: + + 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 @@ format specification typically modifies the result. The general form of a *standard format specifier* is: - **format_spec**: ["options"]["width_and_precision"]["type"] - **options**: [["fill"]"align"]["sign"]["z"]["#"]["0"] - **fill**: - **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: + 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 @@ Nesting arguments and more complex examples: 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 @@ See also: '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 @@ Character Database as included in the "unicodedata" module. Identifiers are unlimited in length. Case is significant. - **identifier**: "xid_start" "xid_continue"* - **id_start**: - **id_continue**: - **xid_start**: - **xid_continue**: + identifier: xid_start xid_continue* + id_start: + id_continue: + xid_start: + xid_continue: The Unicode category codes mentioned above stand for: @@ -6024,9 +6053,9 @@ trailing underscore characters: 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 @@ present, is executed. 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 @@ e.g., "(3+4j)". Some examples of imaginary literals: '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 @@ of Python that introduce incompatible changes to the language. It 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 @@ The operator "not in" is defined to have the inverse truth value of 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 @@ purposes in literals. '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 @@ statements or annotations. 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 @@ specified, it is used for both. '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 @@ described in the Comparisons section. '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 @@ The power operator binds more tightly than unary operators on its 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 @@ This operation can be customized using the special "__pow__()" and '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 @@ exception was re-raised with the traceback it had when it was caught. '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 @@ object.__contains__(self, item) 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 @@ A slicing selects a range of items in a sequence object (e.g., a 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 @@ str.zfill(width) 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**: - **longstringchar**: - **stringescapeseq**: "\\" - - **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**: - **longbyteschar**: - **bytesescapeseq**: "\\" + shortstring: "'" shortstringitem* "'" | '"' shortstringitem* '"' + longstring: "\'\'\'" longstringitem* "\'\'\'" | '"""' longstringitem* '"""' + shortstringitem: shortstringchar | stringescapeseq + longstringitem: longstringchar | stringescapeseq + shortstringchar: + longstringchar: + stringescapeseq: "\\" + + 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: + longbyteschar: + bytesescapeseq: "\\" One syntactic restriction not indicated by these productions is that whitespace is not allowed between the "stringprefix" or "bytesprefix" @@ -9959,7 +9988,7 @@ The subscription of an instance of a container class will generally 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 @@ and "and" always return one of their operands.) 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 @@ there is a saved exception it is re-raised at the end of the "finally" 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 @@ also executed ‘on the way out.’ 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 @@ Notes: 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 @@ In all three cases, if the argument does not have the proper type, a 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 @@ methods defined by a context manager (see section With Statement 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 @@ See also: '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 -- cgit v0.12