756 lines
52 KiB
HTML
756 lines
52 KiB
HTML
|
||
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<meta name="color-scheme" content="light dark">
|
||
<title>PEP 634 – Structural Pattern Matching: Specification | peps.python.org</title>
|
||
<link rel="shortcut icon" href="../_static/py.png">
|
||
<link rel="canonical" href="https://peps.python.org/pep-0634/">
|
||
<link rel="stylesheet" href="../_static/style.css" type="text/css">
|
||
<link rel="stylesheet" href="../_static/mq.css" type="text/css">
|
||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" media="(prefers-color-scheme: light)" id="pyg-light">
|
||
<link rel="stylesheet" href="../_static/pygments_dark.css" type="text/css" media="(prefers-color-scheme: dark)" id="pyg-dark">
|
||
<link rel="alternate" type="application/rss+xml" title="Latest PEPs" href="https://peps.python.org/peps.rss">
|
||
<meta property="og:title" content='PEP 634 – Structural Pattern Matching: Specification | peps.python.org'>
|
||
<meta property="og:description" content="This PEP provides the technical specification for the match statement. It replaces PEP 622, which is hereby split in three parts:">
|
||
<meta property="og:type" content="website">
|
||
<meta property="og:url" content="https://peps.python.org/pep-0634/">
|
||
<meta property="og:site_name" content="Python Enhancement Proposals (PEPs)">
|
||
<meta property="og:image" content="https://peps.python.org/_static/og-image.png">
|
||
<meta property="og:image:alt" content="Python PEPs">
|
||
<meta property="og:image:width" content="200">
|
||
<meta property="og:image:height" content="200">
|
||
<meta name="description" content="This PEP provides the technical specification for the match statement. It replaces PEP 622, which is hereby split in three parts:">
|
||
<meta name="theme-color" content="#3776ab">
|
||
</head>
|
||
<body>
|
||
|
||
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
|
||
<symbol id="svg-sun-half" viewBox="0 0 24 24" pointer-events="all">
|
||
<title>Following system colour scheme</title>
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
|
||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||
<circle cx="12" cy="12" r="9"></circle>
|
||
<path d="M12 3v18m0-12l4.65-4.65M12 14.3l7.37-7.37M12 19.6l8.85-8.85"></path>
|
||
</svg>
|
||
</symbol>
|
||
<symbol id="svg-moon" viewBox="0 0 24 24" pointer-events="all">
|
||
<title>Selected dark colour scheme</title>
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
|
||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
||
<path d="M12 3c.132 0 .263 0 .393 0a7.5 7.5 0 0 0 7.92 12.446a9 9 0 1 1 -8.313 -12.454z"></path>
|
||
</svg>
|
||
</symbol>
|
||
<symbol id="svg-sun" viewBox="0 0 24 24" pointer-events="all">
|
||
<title>Selected light colour scheme</title>
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
|
||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||
<circle cx="12" cy="12" r="5"></circle>
|
||
<line x1="12" y1="1" x2="12" y2="3"></line>
|
||
<line x1="12" y1="21" x2="12" y2="23"></line>
|
||
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
|
||
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
|
||
<line x1="1" y1="12" x2="3" y2="12"></line>
|
||
<line x1="21" y1="12" x2="23" y2="12"></line>
|
||
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
|
||
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
|
||
</svg>
|
||
</symbol>
|
||
</svg>
|
||
<script>
|
||
|
||
document.documentElement.dataset.colour_scheme = localStorage.getItem("colour_scheme") || "auto"
|
||
</script>
|
||
<section id="pep-page-section">
|
||
<header>
|
||
<h1>Python Enhancement Proposals</h1>
|
||
<ul class="breadcrumbs">
|
||
<li><a href="https://www.python.org/" title="The Python Programming Language">Python</a> » </li>
|
||
<li><a href="../pep-0000/">PEP Index</a> » </li>
|
||
<li>PEP 634</li>
|
||
</ul>
|
||
<button id="colour-scheme-cycler" onClick="setColourScheme(nextColourScheme())">
|
||
<svg aria-hidden="true" class="colour-scheme-icon-when-auto"><use href="#svg-sun-half"></use></svg>
|
||
<svg aria-hidden="true" class="colour-scheme-icon-when-dark"><use href="#svg-moon"></use></svg>
|
||
<svg aria-hidden="true" class="colour-scheme-icon-when-light"><use href="#svg-sun"></use></svg>
|
||
<span class="visually-hidden">Toggle light / dark / auto colour theme</span>
|
||
</button>
|
||
</header>
|
||
<article>
|
||
<section id="pep-content">
|
||
<h1 class="page-title">PEP 634 – Structural Pattern Matching: Specification</h1>
|
||
<dl class="rfc2822 field-list simple">
|
||
<dt class="field-odd">Author<span class="colon">:</span></dt>
|
||
<dd class="field-odd">Brandt Bucher <brandt at python.org>,
|
||
Guido van Rossum <guido at python.org></dd>
|
||
<dt class="field-even">BDFL-Delegate<span class="colon">:</span></dt>
|
||
<dd class="field-even"><p></p></dd>
|
||
<dt class="field-odd">Discussions-To<span class="colon">:</span></dt>
|
||
<dd class="field-odd"><a class="reference external" href="https://mail.python.org/archives/list/python-dev@python.org/">Python-Dev list</a></dd>
|
||
<dt class="field-even">Status<span class="colon">:</span></dt>
|
||
<dd class="field-even"><abbr title="Accepted and implementation complete, or no longer active">Final</abbr></dd>
|
||
<dt class="field-odd">Type<span class="colon">:</span></dt>
|
||
<dd class="field-odd"><abbr title="Normative PEP with a new feature for Python, implementation change for CPython or interoperability standard for the ecosystem">Standards Track</abbr></dd>
|
||
<dt class="field-even">Created<span class="colon">:</span></dt>
|
||
<dd class="field-even">12-Sep-2020</dd>
|
||
<dt class="field-odd">Python-Version<span class="colon">:</span></dt>
|
||
<dd class="field-odd">3.10</dd>
|
||
<dt class="field-even">Post-History<span class="colon">:</span></dt>
|
||
<dd class="field-even">22-Oct-2020, 08-Feb-2021</dd>
|
||
<dt class="field-odd">Replaces<span class="colon">:</span></dt>
|
||
<dd class="field-odd"><a class="reference external" href="../pep-0622/">622</a></dd>
|
||
<dt class="field-even">Resolution<span class="colon">:</span></dt>
|
||
<dd class="field-even"><a class="reference external" href="https://mail.python.org/archives/list/python-committers@python.org/message/SQC2FTLFV5A7DV7RCEAR2I2IKJKGK7W3">Python-Committers message</a></dd>
|
||
</dl>
|
||
<hr class="docutils" />
|
||
<section id="contents">
|
||
<details><summary>Table of Contents</summary><ul class="simple">
|
||
<li><a class="reference internal" href="#abstract">Abstract</a></li>
|
||
<li><a class="reference internal" href="#syntax-and-semantics">Syntax and Semantics</a><ul>
|
||
<li><a class="reference internal" href="#overview-and-terminology">Overview and Terminology</a></li>
|
||
<li><a class="reference internal" href="#the-match-statement">The Match Statement</a><ul>
|
||
<li><a class="reference internal" href="#match-semantics">Match Semantics</a></li>
|
||
<li><a class="reference internal" href="#guards">Guards</a></li>
|
||
<li><a class="reference internal" href="#irrefutable-case-blocks">Irrefutable case blocks</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#patterns">Patterns</a><ul>
|
||
<li><a class="reference internal" href="#as-patterns">AS Patterns</a></li>
|
||
<li><a class="reference internal" href="#or-patterns">OR Patterns</a></li>
|
||
<li><a class="reference internal" href="#literal-patterns">Literal Patterns</a></li>
|
||
<li><a class="reference internal" href="#capture-patterns">Capture Patterns</a></li>
|
||
<li><a class="reference internal" href="#wildcard-pattern">Wildcard Pattern</a></li>
|
||
<li><a class="reference internal" href="#value-patterns">Value Patterns</a></li>
|
||
<li><a class="reference internal" href="#group-patterns">Group Patterns</a></li>
|
||
<li><a class="reference internal" href="#sequence-patterns">Sequence Patterns</a></li>
|
||
<li><a class="reference internal" href="#mapping-patterns">Mapping Patterns</a></li>
|
||
<li><a class="reference internal" href="#class-patterns">Class Patterns</a></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#side-effects-and-undefined-behavior">Side Effects and Undefined Behavior</a></li>
|
||
<li><a class="reference internal" href="#the-standard-library">The Standard Library</a></li>
|
||
<li><a class="reference internal" href="#appendix-a-full-grammar">Appendix A – Full Grammar</a></li>
|
||
<li><a class="reference internal" href="#copyright">Copyright</a></li>
|
||
</ul>
|
||
</details></section>
|
||
<div class="pep-banner canonical-doc sticky-banner admonition important">
|
||
<p class="admonition-title">Important</p>
|
||
<p>This PEP is a historical document. The up-to-date, canonical documentation can now be found at <a class="reference external" href="https://docs.python.org/3/reference/compound_stmts.html#match" title="(in Python v3.13)"><span>The match statement</span></a>.</p>
|
||
<p class="close-button">×</p>
|
||
<p>See <a class="pep reference internal" href="../pep-0001/" title="PEP 1 – PEP Purpose and Guidelines">PEP 1</a> for how to propose changes.</p>
|
||
</div>
|
||
<section id="abstract">
|
||
<h2><a class="toc-backref" href="#abstract" role="doc-backlink">Abstract</a></h2>
|
||
<p>This PEP provides the technical specification for the match
|
||
statement. It replaces <a class="pep reference internal" href="../pep-0622/" title="PEP 622 – Structural Pattern Matching">PEP 622</a>, which is hereby split in three parts:</p>
|
||
<ul class="simple">
|
||
<li><a class="pep reference internal" href="../pep-0634/" title="PEP 634 – Structural Pattern Matching: Specification">PEP 634</a>: Specification</li>
|
||
<li><a class="pep reference internal" href="../pep-0635/" title="PEP 635 – Structural Pattern Matching: Motivation and Rationale">PEP 635</a>: Motivation and Rationale</li>
|
||
<li><a class="pep reference internal" href="../pep-0636/" title="PEP 636 – Structural Pattern Matching: Tutorial">PEP 636</a>: Tutorial</li>
|
||
</ul>
|
||
<p>This PEP is intentionally devoid of commentary; the motivation and all
|
||
explanations of our design choices are in <a class="pep reference internal" href="../pep-0635/" title="PEP 635 – Structural Pattern Matching: Motivation and Rationale">PEP 635</a>. First-time readers
|
||
are encouraged to start with <a class="pep reference internal" href="../pep-0636/" title="PEP 636 – Structural Pattern Matching: Tutorial">PEP 636</a>, which provides a gentler
|
||
introduction to the concepts, syntax and semantics of patterns.</p>
|
||
</section>
|
||
<section id="syntax-and-semantics">
|
||
<h2><a class="toc-backref" href="#syntax-and-semantics" role="doc-backlink">Syntax and Semantics</a></h2>
|
||
<p>See <a class="reference internal" href="#appendix-a">Appendix A</a> for the complete grammar.</p>
|
||
<section id="overview-and-terminology">
|
||
<h3><a class="toc-backref" href="#overview-and-terminology" role="doc-backlink">Overview and Terminology</a></h3>
|
||
<p>The pattern matching process takes as input a pattern (following
|
||
<code class="docutils literal notranslate"><span class="pre">case</span></code>) and a subject value (following <code class="docutils literal notranslate"><span class="pre">match</span></code>). Phrases to
|
||
describe the process include “the pattern is matched with (or against)
|
||
the subject value” and “we match the pattern against (or with) the
|
||
subject value”.</p>
|
||
<p>The primary outcome of pattern matching is success or failure. In
|
||
case of success we may say “the pattern succeeds”, “the match
|
||
succeeds”, or “the pattern matches the subject value”.</p>
|
||
<p>In many cases a pattern contains subpatterns, and success or failure
|
||
is determined by the success or failure of matching those subpatterns
|
||
against the value (e.g., for OR patterns) or against parts of the
|
||
value (e.g., for sequence patterns). This process typically processes
|
||
the subpatterns from left to right until the overall outcome is
|
||
determined. E.g., an OR pattern succeeds at the first succeeding
|
||
subpattern, while a sequence patterns fails at the first failing
|
||
subpattern.</p>
|
||
<p>A secondary outcome of pattern matching may be one or more name
|
||
bindings. We may say “the pattern binds a value to a name”. When
|
||
subpatterns tried until the first success, only the bindings due to
|
||
the successful subpattern are valid; when trying until the first
|
||
failure, the bindings are merged. Several more rules, explained
|
||
below, apply to these cases.</p>
|
||
</section>
|
||
<section id="the-match-statement">
|
||
<h3><a class="toc-backref" href="#the-match-statement" role="doc-backlink">The Match Statement</a></h3>
|
||
<p>Syntax:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>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
|
||
guard: 'if' named_expression
|
||
</pre></div>
|
||
</div>
|
||
<p>The rules <code class="docutils literal notranslate"><span class="pre">star_named_expression</span></code>, <code class="docutils literal notranslate"><span class="pre">star_named_expressions</span></code>,
|
||
<code class="docutils literal notranslate"><span class="pre">named_expression</span></code> and <code class="docutils literal notranslate"><span class="pre">block</span></code> are part of the <a class="reference external" href="https://docs.python.org/3.10/reference/grammar.html">standard Python
|
||
grammar</a>.</p>
|
||
<p>The rule <code class="docutils literal notranslate"><span class="pre">patterns</span></code> is specified below.</p>
|
||
<p>For context, <code class="docutils literal notranslate"><span class="pre">match_stmt</span></code> is a new alternative for
|
||
<code class="docutils literal notranslate"><span class="pre">compound_statement</span></code>:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">compound_statement</span><span class="p">:</span>
|
||
<span class="o">|</span> <span class="n">if_stmt</span>
|
||
<span class="o">...</span>
|
||
<span class="o">|</span> <span class="n">match_stmt</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>The <code class="docutils literal notranslate"><span class="pre">match</span></code> and <code class="docutils literal notranslate"><span class="pre">case</span></code> keywords are soft keywords, i.e. they are
|
||
not reserved words in other grammatical contexts (including at the
|
||
start of a line if there is no colon where expected). This implies
|
||
that they are recognized as keywords when part of a match
|
||
statement or case block only, and are allowed to be used in all
|
||
other contexts as variable or argument names.</p>
|
||
<section id="match-semantics">
|
||
<h4><a class="toc-backref" href="#match-semantics" role="doc-backlink">Match Semantics</a></h4>
|
||
<p>The match statement first evaluates the subject expression. If a
|
||
comma is present a tuple is constructed using the standard rules.</p>
|
||
<p>The resulting subject value is then used to select the first case
|
||
block whose patterns succeeds matching it <em>and</em> whose guard condition
|
||
(if present) is “truthy”. If no case blocks qualify the match
|
||
statement is complete; otherwise, the block of the selected case block
|
||
is executed. The usual rules for executing a block nested inside a
|
||
compound statement apply (e.g. an <code class="docutils literal notranslate"><span class="pre">if</span></code> statement).</p>
|
||
<p>Name bindings made during a successful pattern match outlive the
|
||
executed block and can be used after the match statement.</p>
|
||
<p>During failed pattern matches, some subpatterns may succeed. For
|
||
example, while matching the pattern <code class="docutils literal notranslate"><span class="pre">(0,</span> <span class="pre">x,</span> <span class="pre">1)</span></code> with the value <code class="docutils literal notranslate"><span class="pre">[0,</span>
|
||
<span class="pre">1,</span> <span class="pre">2]</span></code>, the subpattern <code class="docutils literal notranslate"><span class="pre">x</span></code> may succeed if the list elements are
|
||
matched from left to right. The implementation may choose to either
|
||
make persistent bindings for those partial matches or not. User code
|
||
including a match statement should not rely on the bindings being
|
||
made for a failed match, but also shouldn’t assume that variables are
|
||
unchanged by a failed match. This part of the behavior is left
|
||
intentionally unspecified so different implementations can add
|
||
optimizations, and to prevent introducing semantic restrictions that
|
||
could limit the extensibility of this feature.</p>
|
||
<p>The precise pattern binding rules vary per pattern type and are
|
||
specified below.</p>
|
||
</section>
|
||
<section id="guards">
|
||
<span id="id1"></span><h4><a class="toc-backref" href="#guards" role="doc-backlink">Guards</a></h4>
|
||
<p>If a guard is present on a case block, once the pattern or patterns in
|
||
the case block succeed, the expression in the guard is evaluated. If
|
||
this raises an exception, the exception bubbles up. Otherwise, if the
|
||
condition is “truthy” the case block is selected; if it is “falsy” the
|
||
case block is not selected.</p>
|
||
<p>Since guards are expressions they are allowed to have side effects.
|
||
Guard evaluation must proceed from the first to the last case block,
|
||
one at a time, skipping case blocks whose pattern(s) don’t all
|
||
succeed. (I.e., even if determining whether those patterns succeed
|
||
may happen out of order, guard evaluation must happen in order.)
|
||
Guard evaluation must stop once a case block is selected.</p>
|
||
</section>
|
||
<section id="irrefutable-case-blocks">
|
||
<h4><a class="toc-backref" href="#irrefutable-case-blocks" role="doc-backlink">Irrefutable case blocks</a></h4>
|
||
<p>A pattern is considered irrefutable if we can prove from its syntax
|
||
alone that it will always succeed. In particular, capture patterns
|
||
and wildcard patterns are irrefutable, and so are AS patterns whose
|
||
left-hand side is irrefutable, OR patterns containing at least
|
||
one irrefutable pattern, and parenthesized irrefutable patterns.</p>
|
||
<p>A case block is considered irrefutable if it has no guard and its
|
||
pattern is irrefutable.</p>
|
||
<p>A match statement may have at most one irrefutable case block, and it
|
||
must be last.</p>
|
||
</section>
|
||
</section>
|
||
<section id="patterns">
|
||
<span id="id2"></span><h3><a class="toc-backref" href="#patterns" role="doc-backlink">Patterns</a></h3>
|
||
<p>The top-level syntax for patterns is as follows:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">patterns</span><span class="p">:</span> <span class="n">open_sequence_pattern</span> <span class="o">|</span> <span class="n">pattern</span>
|
||
<span class="n">pattern</span><span class="p">:</span> <span class="n">as_pattern</span> <span class="o">|</span> <span class="n">or_pattern</span>
|
||
<span class="n">as_pattern</span><span class="p">:</span> <span class="n">or_pattern</span> <span class="s1">'as'</span> <span class="n">capture_pattern</span>
|
||
<span class="n">or_pattern</span><span class="p">:</span> <span class="s1">'|'</span><span class="o">.</span><span class="n">closed_pattern</span><span class="o">+</span>
|
||
<span class="n">closed_pattern</span><span class="p">:</span>
|
||
<span class="o">|</span> <span class="n">literal_pattern</span>
|
||
<span class="o">|</span> <span class="n">capture_pattern</span>
|
||
<span class="o">|</span> <span class="n">wildcard_pattern</span>
|
||
<span class="o">|</span> <span class="n">value_pattern</span>
|
||
<span class="o">|</span> <span class="n">group_pattern</span>
|
||
<span class="o">|</span> <span class="n">sequence_pattern</span>
|
||
<span class="o">|</span> <span class="n">mapping_pattern</span>
|
||
<span class="o">|</span> <span class="n">class_pattern</span>
|
||
</pre></div>
|
||
</div>
|
||
<section id="as-patterns">
|
||
<h4><a class="toc-backref" href="#as-patterns" role="doc-backlink">AS Patterns</a></h4>
|
||
<p>Syntax:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">as_pattern</span><span class="p">:</span> <span class="n">or_pattern</span> <span class="s1">'as'</span> <span class="n">capture_pattern</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>(Note: the name on the right may not be <code class="docutils literal notranslate"><span class="pre">_</span></code>.)</p>
|
||
<p>An AS pattern matches the OR pattern on the left of the <code class="docutils literal notranslate"><span class="pre">as</span></code>
|
||
keyword against the subject. If this fails, the AS pattern fails.
|
||
Otherwise, the AS pattern binds the subject to the name on the right
|
||
of the <code class="docutils literal notranslate"><span class="pre">as</span></code> keyword and succeeds.</p>
|
||
</section>
|
||
<section id="or-patterns">
|
||
<h4><a class="toc-backref" href="#or-patterns" role="doc-backlink">OR Patterns</a></h4>
|
||
<p>Syntax:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">or_pattern</span><span class="p">:</span> <span class="s1">'|'</span><span class="o">.</span><span class="n">closed_pattern</span><span class="o">+</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>When two or more patterns are separated by vertical bars (<code class="docutils literal notranslate"><span class="pre">|</span></code>),
|
||
this is called an OR pattern. (A single closed pattern is just that.)</p>
|
||
<p>Only the final subpattern may be irrefutable.</p>
|
||
<p>Each subpattern must bind the same set of names.</p>
|
||
<p>An OR pattern matches each of its subpatterns in turn to the subject,
|
||
until one succeeds. The OR pattern is then deemed to succeed.
|
||
If none of the subpatterns succeed the OR pattern fails.</p>
|
||
</section>
|
||
<section id="literal-patterns">
|
||
<span id="literal-pattern"></span><h4><a class="toc-backref" href="#literal-patterns" role="doc-backlink">Literal Patterns</a></h4>
|
||
<p>Syntax:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">literal_pattern</span><span class="p">:</span>
|
||
<span class="o">|</span> <span class="n">signed_number</span>
|
||
<span class="o">|</span> <span class="n">signed_number</span> <span class="s1">'+'</span> <span class="n">NUMBER</span>
|
||
<span class="o">|</span> <span class="n">signed_number</span> <span class="s1">'-'</span> <span class="n">NUMBER</span>
|
||
<span class="o">|</span> <span class="n">strings</span>
|
||
<span class="o">|</span> <span class="s1">'None'</span>
|
||
<span class="o">|</span> <span class="s1">'True'</span>
|
||
<span class="o">|</span> <span class="s1">'False'</span>
|
||
<span class="n">signed_number</span><span class="p">:</span> <span class="n">NUMBER</span> <span class="o">|</span> <span class="s1">'-'</span> <span class="n">NUMBER</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>The rule <code class="docutils literal notranslate"><span class="pre">strings</span></code> and the token <code class="docutils literal notranslate"><span class="pre">NUMBER</span></code> are defined in the
|
||
standard Python grammar.</p>
|
||
<p>Triple-quoted strings are supported. Raw strings and byte strings
|
||
are supported. F-strings are not supported.</p>
|
||
<p>The forms <code class="docutils literal notranslate"><span class="pre">signed_number</span> <span class="pre">'+'</span> <span class="pre">NUMBER</span></code> and <code class="docutils literal notranslate"><span class="pre">signed_number</span> <span class="pre">'-'</span>
|
||
<span class="pre">NUMBER</span></code> are only permitted to express complex numbers; they require a
|
||
real number on the left and an imaginary number on the right.</p>
|
||
<p>A literal pattern succeeds if the subject value compares equal to the
|
||
value expressed by the literal, using the following comparisons rules:</p>
|
||
<ul class="simple">
|
||
<li>Numbers and strings are compared using the <code class="docutils literal notranslate"><span class="pre">==</span></code> operator.</li>
|
||
<li>The singleton literals <code class="docutils literal notranslate"><span class="pre">None</span></code>, <code class="docutils literal notranslate"><span class="pre">True</span></code> and <code class="docutils literal notranslate"><span class="pre">False</span></code> are compared
|
||
using the <code class="docutils literal notranslate"><span class="pre">is</span></code> operator.</li>
|
||
</ul>
|
||
</section>
|
||
<section id="capture-patterns">
|
||
<span id="capture-pattern"></span><h4><a class="toc-backref" href="#capture-patterns" role="doc-backlink">Capture Patterns</a></h4>
|
||
<p>Syntax:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>capture_pattern: !"_" NAME
|
||
</pre></div>
|
||
</div>
|
||
<p>The single underscore (<code class="docutils literal notranslate"><span class="pre">_</span></code>) is not a capture pattern (this is what
|
||
<code class="docutils literal notranslate"><span class="pre">!"_"</span></code> expresses). It is treated as a <a class="reference internal" href="#id3">wildcard pattern</a>.</p>
|
||
<p>A capture pattern always succeeds. It binds the subject value to the
|
||
name using the scoping rules for name binding established for the
|
||
walrus operator in <a class="pep reference internal" href="../pep-0572/" title="PEP 572 – Assignment Expressions">PEP 572</a>. (Summary: the name becomes a local
|
||
variable in the closest containing function scope unless there’s an
|
||
applicable <code class="docutils literal notranslate"><span class="pre">nonlocal</span></code> or <code class="docutils literal notranslate"><span class="pre">global</span></code> statement.)</p>
|
||
<p>In a given pattern, a given name may be bound only once. This
|
||
disallows for example <code class="docutils literal notranslate"><span class="pre">case</span> <span class="pre">x,</span> <span class="pre">x:</span> <span class="pre">...</span></code> but allows <code class="docutils literal notranslate"><span class="pre">case</span> <span class="pre">[x]</span> <span class="pre">|</span> <span class="pre">x:</span>
|
||
<span class="pre">...</span></code>.</p>
|
||
</section>
|
||
<section id="wildcard-pattern">
|
||
<span id="id3"></span><h4><a class="toc-backref" href="#wildcard-pattern" role="doc-backlink">Wildcard Pattern</a></h4>
|
||
<p>Syntax:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">wildcard_pattern</span><span class="p">:</span> <span class="s2">"_"</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>A wildcard pattern always succeeds. It binds no name.</p>
|
||
</section>
|
||
<section id="value-patterns">
|
||
<h4><a class="toc-backref" href="#value-patterns" role="doc-backlink">Value Patterns</a></h4>
|
||
<p>Syntax:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">value_pattern</span><span class="p">:</span> <span class="n">attr</span>
|
||
<span class="n">attr</span><span class="p">:</span> <span class="n">name_or_attr</span> <span class="s1">'.'</span> <span class="n">NAME</span>
|
||
<span class="n">name_or_attr</span><span class="p">:</span> <span class="n">attr</span> <span class="o">|</span> <span class="n">NAME</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>The dotted name in the pattern is looked up using the standard Python
|
||
name resolution rules. However, when the same value pattern occurs
|
||
multiple times in the same match statement, the interpreter may cache
|
||
the first value found and reuse it, rather than repeat the same
|
||
lookup. (To clarify, this cache is strictly tied to a given execution
|
||
of a given match statement.)</p>
|
||
<p>The pattern succeeds if the value found thus compares equal to the
|
||
subject value (using the <code class="docutils literal notranslate"><span class="pre">==</span></code> operator).</p>
|
||
</section>
|
||
<section id="group-patterns">
|
||
<h4><a class="toc-backref" href="#group-patterns" role="doc-backlink">Group Patterns</a></h4>
|
||
<p>Syntax:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">group_pattern</span><span class="p">:</span> <span class="s1">'('</span> <span class="n">pattern</span> <span class="s1">')'</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>(For the syntax of <code class="docutils literal notranslate"><span class="pre">pattern</span></code>, see Patterns above. Note that it
|
||
contains no comma – a parenthesized series of items with at least one
|
||
comma is a sequence pattern, as is <code class="docutils literal notranslate"><span class="pre">()</span></code>.)</p>
|
||
<p>A parenthesized pattern has no additional syntax. It allows users to
|
||
add parentheses around patterns to emphasize the intended grouping.</p>
|
||
</section>
|
||
<section id="sequence-patterns">
|
||
<span id="sequence-pattern"></span><h4><a class="toc-backref" href="#sequence-patterns" role="doc-backlink">Sequence Patterns</a></h4>
|
||
<p>Syntax:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>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)
|
||
</pre></div>
|
||
</div>
|
||
<p>(Note that a single parenthesized pattern without a trailing comma is
|
||
a group pattern, not a sequence pattern. However a single pattern
|
||
enclosed in <code class="docutils literal notranslate"><span class="pre">[...]</span></code> is still a sequence pattern.)</p>
|
||
<p>There is no semantic difference between a sequence pattern using
|
||
<code class="docutils literal notranslate"><span class="pre">[...]</span></code>, a sequence pattern using <code class="docutils literal notranslate"><span class="pre">(...)</span></code>, and an open sequence
|
||
pattern.</p>
|
||
<p>A sequence pattern may contain at most one star subpattern. The star
|
||
subpattern may occur in any position. If no star subpattern is
|
||
present, the sequence pattern is a fixed-length sequence pattern;
|
||
otherwise it is a variable-length sequence pattern.</p>
|
||
<p>For a sequence pattern to succeed the subject must be a sequence,
|
||
where being a sequence is defined as its class being one of the following:</p>
|
||
<ul class="simple">
|
||
<li>a class that inherits from <code class="docutils literal notranslate"><span class="pre">collections.abc.Sequence</span></code></li>
|
||
<li>a Python class that has been registered as a <code class="docutils literal notranslate"><span class="pre">collections.abc.Sequence</span></code></li>
|
||
<li>a builtin class that has its <code class="docutils literal notranslate"><span class="pre">Py_TPFLAGS_SEQUENCE</span></code> bit set</li>
|
||
<li>a class that inherits from any of the above (including classes defined <em>before</em> a
|
||
parent’s <code class="docutils literal notranslate"><span class="pre">Sequence</span></code> registration)</li>
|
||
</ul>
|
||
<p>The following standard library classes will have their <code class="docutils literal notranslate"><span class="pre">Py_TPFLAGS_SEQUENCE</span></code>
|
||
bit set:</p>
|
||
<ul class="simple">
|
||
<li><code class="docutils literal notranslate"><span class="pre">array.array</span></code></li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">collections.deque</span></code></li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">list</span></code></li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">memoryview</span></code></li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">range</span></code></li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">tuple</span></code></li>
|
||
</ul>
|
||
<div class="admonition note">
|
||
<p class="admonition-title">Note</p>
|
||
<p>Although <code class="docutils literal notranslate"><span class="pre">str</span></code>, <code class="docutils literal notranslate"><span class="pre">bytes</span></code>, and <code class="docutils literal notranslate"><span class="pre">bytearray</span></code> are usually
|
||
considered sequences, they are not included in the above list and do
|
||
not match sequence patterns.</p>
|
||
</div>
|
||
<p>A fixed-length sequence pattern fails if the length of the subject
|
||
sequence is not equal to the number of subpatterns.</p>
|
||
<p>A variable-length sequence pattern fails if the length of the subject
|
||
sequence is less than the number of non-star subpatterns.</p>
|
||
<p>The length of the subject sequence is obtained using the builtin
|
||
<code class="docutils literal notranslate"><span class="pre">len()</span></code> function (i.e., via the <code class="docutils literal notranslate"><span class="pre">__len__</span></code> protocol). However, the
|
||
interpreter may cache this value in a similar manner as described for
|
||
value patterns.</p>
|
||
<p>A fixed-length sequence pattern matches the subpatterns to
|
||
corresponding items of the subject sequence, from left to right.
|
||
Matching stops (with a failure) as soon as a subpattern fails. If all
|
||
subpatterns succeed in matching their corresponding item, the sequence
|
||
pattern succeeds.</p>
|
||
<p>A variable-length sequence pattern first matches the leading non-star
|
||
subpatterns to the corresponding items of the subject sequence, as for
|
||
a fixed-length sequence. If this succeeds, the star subpattern
|
||
matches a list formed of the remaining subject items, with items
|
||
removed from the end corresponding to the non-star subpatterns
|
||
following the star subpattern. The remaining non-star subpatterns are
|
||
then matched to the corresponding subject items, as for a fixed-length
|
||
sequence.</p>
|
||
</section>
|
||
<section id="mapping-patterns">
|
||
<span id="mapping-pattern"></span><h4><a class="toc-backref" href="#mapping-patterns" role="doc-backlink">Mapping Patterns</a></h4>
|
||
<p>Syntax:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>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
|
||
</pre></div>
|
||
</div>
|
||
<p>(Note that <code class="docutils literal notranslate"><span class="pre">**_</span></code> is disallowed by this syntax.)</p>
|
||
<p>A mapping pattern may contain at most one double star pattern,
|
||
and it must be last.</p>
|
||
<p>A mapping pattern may not contain duplicate key values.
|
||
(If all key patterns are literal patterns this is considered a
|
||
syntax error; otherwise this is a runtime error and will
|
||
raise <code class="docutils literal notranslate"><span class="pre">ValueError</span></code>.)</p>
|
||
<p>For a mapping pattern to succeed the subject must be a mapping,
|
||
where being a mapping is defined as its class being one of the following:</p>
|
||
<ul class="simple">
|
||
<li>a class that inherits from <code class="docutils literal notranslate"><span class="pre">collections.abc.Mapping</span></code></li>
|
||
<li>a Python class that has been registered as a <code class="docutils literal notranslate"><span class="pre">collections.abc.Mapping</span></code></li>
|
||
<li>a builtin class that has its <code class="docutils literal notranslate"><span class="pre">Py_TPFLAGS_MAPPING</span></code> bit set</li>
|
||
<li>a class that inherits from any of the above (including classes defined <em>before</em> a
|
||
parent’s <code class="docutils literal notranslate"><span class="pre">Mapping</span></code> registration)</li>
|
||
</ul>
|
||
<p>The standard library classes <code class="docutils literal notranslate"><span class="pre">dict</span></code> and <code class="docutils literal notranslate"><span class="pre">mappingproxy</span></code> will have their <code class="docutils literal notranslate"><span class="pre">Py_TPFLAGS_MAPPING</span></code>
|
||
bit set.</p>
|
||
<p>A mapping pattern succeeds if every key given in the mapping pattern
|
||
is present in the subject mapping, and the pattern for
|
||
each key matches the corresponding item of the subject mapping. Keys
|
||
are always compared with the <code class="docutils literal notranslate"><span class="pre">==</span></code> operator. If a <code class="docutils literal notranslate"><span class="pre">'**'</span>
|
||
<span class="pre">NAME</span></code> form is present, that name is bound to a <code class="docutils literal notranslate"><span class="pre">dict</span></code> containing
|
||
remaining key-value pairs from the subject mapping.</p>
|
||
<p>If duplicate keys are detected in the mapping pattern, the pattern is
|
||
considered invalid, and a <code class="docutils literal notranslate"><span class="pre">ValueError</span></code> is raised.</p>
|
||
<p>Key-value pairs are matched using the two-argument form of the
|
||
subject’s <code class="docutils literal notranslate"><span class="pre">get()</span></code> method. As a consequence, matched key-value pairs
|
||
must already be present in the mapping, and not created on-the-fly by
|
||
<code class="docutils literal notranslate"><span class="pre">__missing__</span></code> or <code class="docutils literal notranslate"><span class="pre">__getitem__</span></code>. For example,
|
||
<code class="docutils literal notranslate"><span class="pre">collections.defaultdict</span></code> instances will only be matched by patterns
|
||
with keys that were already present when the match statement was
|
||
entered.</p>
|
||
</section>
|
||
<section id="class-patterns">
|
||
<span id="class-pattern"></span><h4><a class="toc-backref" href="#class-patterns" role="doc-backlink">Class Patterns</a></h4>
|
||
<p>Syntax:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>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
|
||
</pre></div>
|
||
</div>
|
||
<p>A class pattern may not repeat the same keyword multiple times.</p>
|
||
<p>If <code class="docutils literal notranslate"><span class="pre">name_or_attr</span></code> is not an instance of the builtin <code class="docutils literal notranslate"><span class="pre">type</span></code>,
|
||
<code class="docutils literal notranslate"><span class="pre">TypeError</span></code> is raised.</p>
|
||
<p>A class pattern fails if the subject is not an instance of <code class="docutils literal notranslate"><span class="pre">name_or_attr</span></code>.
|
||
This is tested using <code class="docutils literal notranslate"><span class="pre">isinstance()</span></code>.</p>
|
||
<p>If no arguments are present, the pattern succeeds if the <code class="docutils literal notranslate"><span class="pre">isinstance()</span></code>
|
||
check succeeds. Otherwise:</p>
|
||
<ul class="simple">
|
||
<li>If only keyword patterns are present, they are processed as follows,
|
||
one by one:<ul>
|
||
<li>The keyword is looked up as an attribute on the subject.<ul>
|
||
<li>If this raises an exception other than <code class="docutils literal notranslate"><span class="pre">AttributeError</span></code>,
|
||
the exception bubbles up.</li>
|
||
<li>If this raises <code class="docutils literal notranslate"><span class="pre">AttributeError</span></code> the class pattern fails.</li>
|
||
<li>Otherwise, the subpattern associated with the keyword is matched
|
||
against the attribute value. If this fails, the class pattern fails.
|
||
If it succeeds, the match proceeds to the next keyword.</li>
|
||
</ul>
|
||
</li>
|
||
<li>If all keyword patterns succeed, the class pattern as a whole succeeds.</li>
|
||
</ul>
|
||
</li>
|
||
<li>If any positional patterns are present, they are converted to keyword
|
||
patterns (see below) and treated as additional keyword patterns,
|
||
preceding the syntactic keyword patterns (if any).</li>
|
||
</ul>
|
||
<p>Positional patterns are converted to keyword patterns using the
|
||
<code class="docutils literal notranslate"><span class="pre">__match_args__</span></code> attribute on the class designated by <code class="docutils literal notranslate"><span class="pre">name_or_attr</span></code>,
|
||
as follows:</p>
|
||
<ul class="simple">
|
||
<li>For a number of built-in types (specified below),
|
||
a single positional subpattern is accepted which will match
|
||
the entire subject. (Keyword patterns work as for other types here.)</li>
|
||
<li>The equivalent of <code class="docutils literal notranslate"><span class="pre">getattr(cls,</span> <span class="pre">"__match_args__",</span> <span class="pre">()))</span></code> is called.</li>
|
||
<li>If this raises an exception the exception bubbles up.</li>
|
||
<li>If the returned value is not a tuple, the conversion fails
|
||
and <code class="docutils literal notranslate"><span class="pre">TypeError</span></code> is raised.</li>
|
||
<li>If there are more positional patterns than the length of
|
||
<code class="docutils literal notranslate"><span class="pre">__match_args__</span></code> (as obtained using <code class="docutils literal notranslate"><span class="pre">len()</span></code>), <code class="docutils literal notranslate"><span class="pre">TypeError</span></code> is raised.</li>
|
||
<li>Otherwise, positional pattern <code class="docutils literal notranslate"><span class="pre">i</span></code> is converted to a keyword pattern
|
||
using <code class="docutils literal notranslate"><span class="pre">__match_args__[i]</span></code> as the keyword,
|
||
provided it the latter is a string;
|
||
if it is not, <code class="docutils literal notranslate"><span class="pre">TypeError</span></code> is raised.</li>
|
||
<li>For duplicate keywords, <code class="docutils literal notranslate"><span class="pre">TypeError</span></code> is raised.</li>
|
||
</ul>
|
||
<p>Once the positional patterns have been converted to keyword patterns,
|
||
the match proceeds as if there were only keyword patterns.</p>
|
||
<p>As mentioned above, for the following built-in types the handling of
|
||
positional subpatterns is different:
|
||
<code class="docutils literal notranslate"><span class="pre">bool</span></code>, <code class="docutils literal notranslate"><span class="pre">bytearray</span></code>, <code class="docutils literal notranslate"><span class="pre">bytes</span></code>, <code class="docutils literal notranslate"><span class="pre">dict</span></code>, <code class="docutils literal notranslate"><span class="pre">float</span></code>,
|
||
<code class="docutils literal notranslate"><span class="pre">frozenset</span></code>, <code class="docutils literal notranslate"><span class="pre">int</span></code>, <code class="docutils literal notranslate"><span class="pre">list</span></code>, <code class="docutils literal notranslate"><span class="pre">set</span></code>, <code class="docutils literal notranslate"><span class="pre">str</span></code>, and <code class="docutils literal notranslate"><span class="pre">tuple</span></code>.</p>
|
||
<p>This behavior is roughly equivalent to the following:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">C</span><span class="p">:</span>
|
||
<span class="n">__match_args__</span> <span class="o">=</span> <span class="p">(</span><span class="s2">"__match_self_prop__"</span><span class="p">,)</span>
|
||
<span class="nd">@property</span>
|
||
<span class="k">def</span> <span class="nf">__match_self_prop__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||
<span class="k">return</span> <span class="bp">self</span>
|
||
</pre></div>
|
||
</div>
|
||
</section>
|
||
</section>
|
||
</section>
|
||
<section id="side-effects-and-undefined-behavior">
|
||
<h2><a class="toc-backref" href="#side-effects-and-undefined-behavior" role="doc-backlink">Side Effects and Undefined Behavior</a></h2>
|
||
<p>The only side-effect produced explicitly by the matching process is
|
||
the binding of names. However, the process relies on attribute
|
||
access, instance checks, <code class="docutils literal notranslate"><span class="pre">len()</span></code>, equality and item access on the
|
||
subject and some of its components. It also evaluates value
|
||
patterns and the class name of class patterns. While none of those
|
||
typically create any side-effects, in theory they could. This
|
||
proposal intentionally leaves out any specification of what methods
|
||
are called or how many times. This behavior is therefore undefined
|
||
and user code should not rely on it.</p>
|
||
<p>Another undefined behavior is the binding of variables by capture
|
||
patterns that are followed (in the same case block) by another pattern
|
||
that fails. These may happen earlier or later depending on the
|
||
implementation strategy, the only constraint being that capture
|
||
variables must be set before guards that use them explicitly are
|
||
evaluated. If a guard consists of an <code class="docutils literal notranslate"><span class="pre">and</span></code> clause, evaluation of
|
||
the operands may even be interspersed with pattern matching, as long
|
||
as left-to-right evaluation order is maintained.</p>
|
||
</section>
|
||
<section id="the-standard-library">
|
||
<h2><a class="toc-backref" href="#the-standard-library" role="doc-backlink">The Standard Library</a></h2>
|
||
<p>To facilitate the use of pattern matching, several changes will be
|
||
made to the standard library:</p>
|
||
<ul class="simple">
|
||
<li>Namedtuples and dataclasses will have auto-generated
|
||
<code class="docutils literal notranslate"><span class="pre">__match_args__</span></code>.</li>
|
||
<li>For dataclasses the order of attributes in the generated
|
||
<code class="docutils literal notranslate"><span class="pre">__match_args__</span></code> will be the same as the order of corresponding
|
||
arguments in the generated <code class="docutils literal notranslate"><span class="pre">__init__()</span></code> method. This includes the
|
||
situations where attributes are inherited from a superclass. Fields
|
||
with <code class="docutils literal notranslate"><span class="pre">init=False</span></code> are excluded from <code class="docutils literal notranslate"><span class="pre">__match_args__</span></code>.</li>
|
||
</ul>
|
||
<p>In addition, a systematic effort will be put into going through
|
||
existing standard library classes and adding <code class="docutils literal notranslate"><span class="pre">__match_args__</span></code> where
|
||
it looks beneficial.</p>
|
||
</section>
|
||
<section id="appendix-a-full-grammar">
|
||
<span id="appendix-a"></span><h2><a class="toc-backref" href="#appendix-a-full-grammar" role="doc-backlink">Appendix A – Full Grammar</a></h2>
|
||
<p>Here is the full grammar for <code class="docutils literal notranslate"><span class="pre">match_stmt</span></code>. This is an additional
|
||
alternative for <code class="docutils literal notranslate"><span class="pre">compound_stmt</span></code>. Remember that <code class="docutils literal notranslate"><span class="pre">match</span></code> and
|
||
<code class="docutils literal notranslate"><span class="pre">case</span></code> are soft keywords, i.e. they are not reserved words in other
|
||
grammatical contexts (including at the start of a line if there is no
|
||
colon where expected). By convention, hard keywords use single quotes
|
||
while soft keywords use double quotes.</p>
|
||
<p>Other notation used beyond standard EBNF:</p>
|
||
<ul class="simple">
|
||
<li><code class="docutils literal notranslate"><span class="pre">SEP.RULE+</span></code> is shorthand for <code class="docutils literal notranslate"><span class="pre">RULE</span> <span class="pre">(SEP</span> <span class="pre">RULE)*</span></code></li>
|
||
<li><code class="docutils literal notranslate"><span class="pre">!RULE</span></code> is a negative lookahead assertion</li>
|
||
</ul>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>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
|
||
guard: 'if' named_expression
|
||
|
||
patterns: open_sequence_pattern | pattern
|
||
pattern: as_pattern | or_pattern
|
||
as_pattern: or_pattern 'as' capture_pattern
|
||
or_pattern: '|'.closed_pattern+
|
||
closed_pattern:
|
||
| literal_pattern
|
||
| capture_pattern
|
||
| wildcard_pattern
|
||
| value_pattern
|
||
| group_pattern
|
||
| sequence_pattern
|
||
| mapping_pattern
|
||
| class_pattern
|
||
|
||
literal_pattern:
|
||
| signed_number !('+' | '-')
|
||
| signed_number '+' NUMBER
|
||
| signed_number '-' NUMBER
|
||
| strings
|
||
| 'None'
|
||
| 'True'
|
||
| 'False'
|
||
signed_number: NUMBER | '-' NUMBER
|
||
|
||
capture_pattern: !"_" NAME !('.' | '(' | '=')
|
||
|
||
wildcard_pattern: "_"
|
||
|
||
value_pattern: attr !('.' | '(' | '=')
|
||
attr: name_or_attr '.' NAME
|
||
name_or_attr: attr | NAME
|
||
|
||
group_pattern: '(' 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)
|
||
|
||
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
|
||
|
||
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
|
||
</pre></div>
|
||
</div>
|
||
</section>
|
||
<section id="copyright">
|
||
<h2><a class="toc-backref" href="#copyright" role="doc-backlink">Copyright</a></h2>
|
||
<p>This document is placed in the public domain or under the
|
||
CC0-1.0-Universal license, whichever is more permissive.</p>
|
||
</section>
|
||
</section>
|
||
<hr class="docutils" />
|
||
<p>Source: <a class="reference external" href="https://github.com/python/peps/blob/main/peps/pep-0634.rst">https://github.com/python/peps/blob/main/peps/pep-0634.rst</a></p>
|
||
<p>Last modified: <a class="reference external" href="https://github.com/python/peps/commits/main/peps/pep-0634.rst">2023-12-11 05:40:56 GMT</a></p>
|
||
|
||
</article>
|
||
<nav id="pep-sidebar">
|
||
<h2>Contents</h2>
|
||
<ul>
|
||
<li><a class="reference internal" href="#abstract">Abstract</a></li>
|
||
<li><a class="reference internal" href="#syntax-and-semantics">Syntax and Semantics</a><ul>
|
||
<li><a class="reference internal" href="#overview-and-terminology">Overview and Terminology</a></li>
|
||
<li><a class="reference internal" href="#the-match-statement">The Match Statement</a><ul>
|
||
<li><a class="reference internal" href="#match-semantics">Match Semantics</a></li>
|
||
<li><a class="reference internal" href="#guards">Guards</a></li>
|
||
<li><a class="reference internal" href="#irrefutable-case-blocks">Irrefutable case blocks</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#patterns">Patterns</a><ul>
|
||
<li><a class="reference internal" href="#as-patterns">AS Patterns</a></li>
|
||
<li><a class="reference internal" href="#or-patterns">OR Patterns</a></li>
|
||
<li><a class="reference internal" href="#literal-patterns">Literal Patterns</a></li>
|
||
<li><a class="reference internal" href="#capture-patterns">Capture Patterns</a></li>
|
||
<li><a class="reference internal" href="#wildcard-pattern">Wildcard Pattern</a></li>
|
||
<li><a class="reference internal" href="#value-patterns">Value Patterns</a></li>
|
||
<li><a class="reference internal" href="#group-patterns">Group Patterns</a></li>
|
||
<li><a class="reference internal" href="#sequence-patterns">Sequence Patterns</a></li>
|
||
<li><a class="reference internal" href="#mapping-patterns">Mapping Patterns</a></li>
|
||
<li><a class="reference internal" href="#class-patterns">Class Patterns</a></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#side-effects-and-undefined-behavior">Side Effects and Undefined Behavior</a></li>
|
||
<li><a class="reference internal" href="#the-standard-library">The Standard Library</a></li>
|
||
<li><a class="reference internal" href="#appendix-a-full-grammar">Appendix A – Full Grammar</a></li>
|
||
<li><a class="reference internal" href="#copyright">Copyright</a></li>
|
||
</ul>
|
||
|
||
<br>
|
||
<a id="source" href="https://github.com/python/peps/blob/main/peps/pep-0634.rst">Page Source (GitHub)</a>
|
||
</nav>
|
||
</section>
|
||
<script src="../_static/colour_scheme.js"></script>
|
||
<script src="../_static/wrap_tables.js"></script>
|
||
<script src="../_static/sticky_banner.js"></script>
|
||
</body>
|
||
</html> |