From af3ce4faba158fe76e56226b08e008371ecd6bea Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Wed, 5 Feb 2025 17:56:56 +0100 Subject: [PATCH 1/4] Fix grammar snippet formatting for help() output Change pydoc_data to show the "input" of grammar snippet directives, which is formatted the way we want. See also this Sphinx issue: https://github.com/sphinx-doc/sphinx/issues/13302 And: https://github.com/sphinx-doc/sphinx/issues/4454 A known issue is cross-grammar links, like those in the string format specification mini-language, which render as reST source: element_index: `~python-grammar:digit`+ | `index_string` I don't see a good way to fix this before Sphinx is refactored. --- Doc/tools/extensions/grammar_snippet.py | 11 ++++++++++- Doc/tools/extensions/pydoc_topics.py | 11 ++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/Doc/tools/extensions/grammar_snippet.py b/Doc/tools/extensions/grammar_snippet.py index 03c7e7ce2f4228..2ff6b16e56b494 100644 --- a/Doc/tools/extensions/grammar_snippet.py +++ b/Doc/tools/extensions/grammar_snippet.py @@ -36,6 +36,12 @@ def __init__( self['classes'].append('sx') +class grammar_snippet(nodes.literal_block): # noqa: N801 (snake_case) + """Node for a grammar snippet""" + + grammar_snippet_content: Sequence[str] + + class GrammarSnippetBase(SphinxDirective): """Common functionality for GrammarSnippetDirective & CompatProductionList.""" @@ -58,11 +64,14 @@ def make_grammar_snippet( # To get around this, we set it to this non-empty string: rawsource = 'You should not see this.' - literal = nodes.literal_block( + literal = grammar_snippet( rawsource, '', classes=['highlight'], ) + # Save a copy of the "input" content. For plain text, we want to + # output this verbatim. + literal.grammar_snippet_content = list(content) grammar_re = re.compile( r""" diff --git a/Doc/tools/extensions/pydoc_topics.py b/Doc/tools/extensions/pydoc_topics.py index 6e43df2e4bf9de..a0aa316c4b04be 100644 --- a/Doc/tools/extensions/pydoc_topics.py +++ b/Doc/tools/extensions/pydoc_topics.py @@ -10,6 +10,7 @@ from sphinx.util.display import status_iterator from sphinx.util.docutils import new_document from sphinx.writers.text import TextTranslator +from docutils import nodes if TYPE_CHECKING: from collections.abc import Sequence, Set @@ -102,6 +103,14 @@ "yield", }) +class PydocTextTranslator(TextTranslator): + def visit_grammar_snippet(self, node: Element) -> None: + """For grammar snippets, return the "input" as is.""" + self.new_state() + self.add_text(self.nl.join(node.grammar_snippet_content)) + self.end_state(wrap=False) + raise nodes.SkipNode + class PydocTopicsBuilder(TextBuilder): name = "pydoc-topics" @@ -141,7 +150,7 @@ def write_documents(self, _docnames: Set[str]) -> None: for topic_label, label_id in label_ids: document = new_document("
") document.append(doc_ids[label_id]) - visitor = TextTranslator(document, builder=self) + visitor = PydocTextTranslator(document, builder=self) document.walkabout(visitor) self.topics[topic_label] = visitor.body From 1af8b9063b70c213e5f1689cc6cbbcaa195f0ef8 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Wed, 5 Feb 2025 18:01:13 +0100 Subject: [PATCH 2/4] Commit the generated pydoc_data changes This is usually done at release time. --- Lib/pydoc_data/topics.py | 624 ++++++++++++++++++++------------------- 1 file changed, 314 insertions(+), 310 deletions(-) diff --git a/Lib/pydoc_data/topics.py b/Lib/pydoc_data/topics.py index 3e8c7ce321edc2..944b012a1b2ba5 100644 --- a/Lib/pydoc_data/topics.py +++ b/Lib/pydoc_data/topics.py @@ -1,4 +1,4 @@ -# Autogenerated by Sphinx on Tue Jan 21 03:33:33 2025 +# Autogenerated by Sphinx on Wed Feb 5 17:32:18 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,10 +195,10 @@ 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 symbols.) @@ -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,10 +864,10 @@ 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 symbols.) @@ -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,9 +1386,9 @@ 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 ::= "<" | ">" | "==" | ">=" | "<=" | "!=" - | "is" ["not"] | ["not"] "in" + comparison: `or_expr` (`comp_operator` `or_expr`)* + comp_operator: "<" | ">" | "==" | ">=" | "<=" | "!=" + | "is" ["not"] | ["not"] "in" Comparisons yield boolean values: "True" or "False". Custom *rich comparison methods* may return non-boolean values. In this case Python @@ -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 @@ -1985,9 +1985,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 +2093,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 +2187,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 +2254,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 +2279,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 +2300,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 +2315,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 - | "None" - | "True" - | "False" - signed_number ::= ["-"] NUMBER + literal_pattern: `signed_number` + | `signed_number` "+" NUMBER + | `signed_number` "-" NUMBER + | `strings` + | "None" + | "True" + | "False" + 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 +2342,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 +2365,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 +2379,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 +2405,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 +2417,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 +2505,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 +2558,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,20 +2690,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 [","]]] - | "**" 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 @@ -2843,9 +2845,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 @@ -2935,8 +2937,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 @@ -2962,7 +2964,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 @@ -3003,7 +3005,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. @@ -3052,11 +3054,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: @@ -3422,7 +3424,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 @@ -3948,9 +3950,9 @@ class pdb.Pdb(completekey='tab', stdin=None, stdout=None, skip=None, nosigint=Fa originate in a module that matches one of these patterns. [1] By default, Pdb sets a handler for the SIGINT signal (which is sent - when the user presses "Ctrl"-"C" on the console) when you give a + when the user presses "Ctrl-C" on the console) when you give a "continue" command. This allows you to break into the debugger - again by pressing "Ctrl"-"C". If you want Pdb not to touch the + again by pressing "Ctrl-C". If you want Pdb not to touch the SIGINT handler, set *nosigint* to true. The *readrc* argument defaults to true and controls whether Pdb @@ -4486,7 +4488,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 @@ -4515,10 +4517,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. @@ -4579,9 +4581,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 @@ -5000,12 +5002,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 @@ -5035,12 +5037,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 @@ -5061,8 +5063,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 @@ -5116,14 +5118,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 ::= + - 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: [`~python-grammar:identifier` | `~python-grammar:digit`+] + attribute_name: `~python-grammar:identifier` + element_index: `~python-grammar: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 @@ -5220,14 +5222,14 @@ class of the instance or a *non-virtual base class* thereof. The The general form of a *standard format specifier* is: - format_spec ::= [[fill]align][sign]["z"]["#"]["0"][width][grouping_option]["." precision][type] - fill ::= - align ::= "<" | ">" | "=" | "^" - sign ::= "+" | "-" | " " - width ::= digit+ - grouping_option ::= "_" | "," - precision ::= digit+ - type ::= "b" | "c" | "d" | "e" | "E" | "f" | "F" | "g" | "G" | "n" | "o" | "s" | "x" | "X" | "%" + format_spec: [[`fill`]`align`][`sign`]["z"]["#"]["0"][`width`][`grouping_option`]["." `precision`][`type`] + fill: + align: "<" | ">" | "=" | "^" + sign: "+" | "-" | " " + width: `~python-grammar:digit`+ + grouping_option: "_" | "," + precision: `~python-grammar: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* character that can be any character and defaults to a space if @@ -5602,7 +5604,7 @@ class of the instance or a *non-virtual base class* thereof. The 3232235521 >>> >>> width = 5 - >>> for num in range(5,12): + >>> for num in range(5,12): ... for base in 'dXob': ... print('{0:{width}{base}}'.format(num, base=base, width=width), end=' ') ... print() @@ -5621,20 +5623,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 [","]]] - | "**" 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 @@ -5770,7 +5774,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 @@ -5853,11 +5857,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 ::= - 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: @@ -5978,9 +5982,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 @@ -5994,7 +5998,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 @@ -6007,14 +6011,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: @@ -6133,11 +6137,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: @@ -6246,16 +6250,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. @@ -6281,7 +6285,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" @@ -6301,7 +6305,7 @@ def (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- @@ -6594,7 +6598,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 @@ -6981,7 +6985,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, @@ -6998,7 +7002,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 @@ -7024,7 +7028,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 @@ -7126,7 +7130,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. @@ -7311,7 +7315,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 @@ -7332,13 +7336,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 @@ -9725,26 +9729,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 ::= - 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" @@ -9908,7 +9912,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. @@ -9988,17 +9992,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 @@ -12607,7 +12611,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 @@ -12630,8 +12634,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 @@ -12651,9 +12655,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: @@ -12754,7 +12758,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 From 1969945f1c581c7cc05af96e9b777d3ff636467c Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Wed, 12 Feb 2025 16:12:27 +0100 Subject: [PATCH 3/4] Fix annotation and run `ruff check Doc/tools/ --fix` --- Doc/tools/extensions/pydoc_topics.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Doc/tools/extensions/pydoc_topics.py b/Doc/tools/extensions/pydoc_topics.py index a0aa316c4b04be..e845a3b3d6db7a 100644 --- a/Doc/tools/extensions/pydoc_topics.py +++ b/Doc/tools/extensions/pydoc_topics.py @@ -5,12 +5,12 @@ from time import asctime from typing import TYPE_CHECKING +from docutils import nodes from sphinx.builders.text import TextBuilder from sphinx.util import logging from sphinx.util.display import status_iterator from sphinx.util.docutils import new_document from sphinx.writers.text import TextTranslator -from docutils import nodes if TYPE_CHECKING: from collections.abc import Sequence, Set @@ -103,8 +103,9 @@ "yield", }) + class PydocTextTranslator(TextTranslator): - def visit_grammar_snippet(self, node: Element) -> None: + def visit_grammar_snippet(self, node: nodes.Element) -> None: """For grammar snippets, return the "input" as is.""" self.new_state() self.add_text(self.nl.join(node.grammar_snippet_content)) From f04e70a8c0717d777a559d03e0e0869b0e9cf3b9 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Wed, 12 Feb 2025 16:29:24 +0100 Subject: [PATCH 4/4] Remove space from autogenerated file --- Lib/pydoc_data/topics.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/pydoc_data/topics.py b/Lib/pydoc_data/topics.py index 4bd0b7b6a0be8d..2f7e90606df6d6 100644 --- a/Lib/pydoc_data/topics.py +++ b/Lib/pydoc_data/topics.py @@ -5614,7 +5614,7 @@ class of the instance or a *non-virtual base class* thereof. The 3232235521 >>> >>> width = 5 - >>> for num in range(5,12): + >>> for num in range(5,12): ... for base in 'dXob': ... print('{0:{width}{base}}'.format(num, base=base, width=width), end=' ') ... print()