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