Python 3.10: structural pattern matching and better error messages

Python 3.10 (4 October 2021): structural pattern matching (match/case), PEP 634/635/636, X | Y union syntax (PEP 604), parenthesized context managers, vastly improved error messages thanks to the new PEG parser.

Open SourceWebR&D PythonPython 3.10Pattern MatchingTypingŁukasz LangaPablo GalindoOpen Source

October 2021

Python 3.10 was released on 4 October 2021, with Pablo Galindo Salgado as Release Manager. The release brings structural changes to the parser (new PEG parser, PEP 617, which arrived in 3.9) and weighty syntactic additions, including the most debated of the 3.x series: pattern matching.

Structural Pattern Matching (PEP 634-636)

The most visible novelty: match / case. Three coordinated PEPs (634 spec, 635 motivation, 636 tutorial). Syntactically inspired by OCaml/Haskell/Scala/Rust, with Pythonic adaptations:

def describe(point):
    match point:
        case (0, 0):
            return "origin"
        case (x, 0):
            return f"on X axis (x={x})"
        case (0, y):
            return f"on Y axis (y={y})"
        case (x, y):
            return f"point ({x}, {y})"
        case _:
            return "unrecognised"

Match is not a C-style switch/case — it is a destructuring pattern match supporting:

  • Literal patternscase 42, case "done", case True
  • Capture patternscase x binds
  • Sequence patternscase [a, b, *rest]
  • Mapping patternscase {"name": name, "age": age}
  • Class patternscase Point(x=0, y=y) — uses __match_args__
  • OR patternscase 1 | 2 | 3
  • Guard patternscase x if x > 0
  • Wildcardcase _

The mechanism integrates with existing protocols (e.g. __match_args__ on dataclass), making matching on complex structures natural.

Type Union syntax (PEP 604)

Another elegant syntax: X | Y replaces Union[X, Y] in type annotations.

# Before (still supported)
from typing import Union
def f(x: Union[int, str]) -> Union[int, None]: ...

# Python 3.10+
def f(x: int | str) -> int | None: ...

The syntax mirrors | use in other typed languages (TypeScript, Kotlin) and makes annotations more readable.

Parenthesized context managers

The new PEG parser (PEP 617) enables multi-line syntax for with:

with (
    open("input.txt") as fin,
    open("output.txt", "w") as fout,
    lock_resource() as resource,
):
    # body
    ...

Formatting multi-manager used to be awkward — required contextlib.ExitStack or backslash continuations. Now it is syntactically clean.

Improved error messages

The new PEG parser enables much more precise error messages:

# Python 3.9
File "foo.py", line 1
    x = {'a': 1, 'b': 2, 'c': 3
                              ^
SyntaxError: invalid syntax

# Python 3.10
File "foo.py", line 1
    x = {'a': 1, 'b': 2, 'c': 3
         ^
SyntaxError: '{' was never closed

Errors indicate cause and not just where the parser choked. Even NameError messages suggest “did you mean…?” for variables with typos.

Other typing contributions

  • Explicit TypeAlias (PEP 613): Vector: TypeAlias = list[float]
  • ParamSpec (PEP 612): typing of decorators preserving signature
  • TypeGuard (PEP 647): explicit type narrowing for runtime checks
  • Concatenate (PEP 612)

zip(strict=True)

zip() accepts strict=True to raise ValueError if iterables have different lengths — useful for debugging unexpected data.

Other novelties

  • Distutils deprecated (removal in 3.12)
  • async with contextlib.aclosing() (PEP 637)
  • int.bit_count() — popcount
  • dict union operators (consolidated from 3.9): d1 | d2

Support and adoption

Python 3.10 has support through October 2026 (standard 5 years). Project adoption is relatively rapid:

  • Black, mypy, ruff add support
  • Django 4.0 (December 2021) supports 3.10
  • FastAPI, Pydantic — full pattern matching support in examples and docs

Performance

Core optimisations:

  • Inline constant literals
  • Optimised store/load
  • struct pack/unpack improved

Average benchmarks: 3-10% faster than 3.9 on typical workloads.

In the Italian context

Python 3.10 diffuses normally:

  • Data science — rapid adoption
  • Backend web — new projects on 3.10 from 2022
  • PA — slower adoption policy; 3.8/3.9 remain dominant for a while

Structural pattern matching is welcomed with interest — similar to match in Rust/Scala, it shifts Python code style toward more functional forms for parsing and state machines.


References: Python 3.10.0 (4 October 2021). Pablo Galindo Salgado as Release Manager. PEP 634/635/636 (pattern matching), PEP 604 (union syntax), PEP 617 (PEG parser), PEP 613 (TypeAlias), PEP 612 (ParamSpec, Concatenate), PEP 647 (TypeGuard).

Need support? Under attack? Service Status
Need support? Under attack? Service Status