Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

The mapping pattern is a structural pattern matching construct introduced in Python 3.10 used to destructure and validate objects that implement the mapping protocol. It verifies the presence of specific keys and applies sub-patterns to their corresponding values, inherently allowing for partial matches by ignoring unspecified keys in the subject.

Syntax

subject = {"literal_key": "value", "extra_key": "extra_value"}

match subject:
    case {"literal_key": value_pattern, **rest_binding}:
        pass

Core Mechanics

  1. Type Validation: The pattern checks if the subject’s class has the Py_TPFLAGS_MAPPING flag set at the C level. This includes built-in types like dict and classes that explicitly inherit from collections.abc.Mapping. Classes registered merely as virtual subclasses via collections.abc.Mapping.register() will fail mapping pattern matching because they lack this C-level flag, even though isinstance(subject, Mapping) evaluates to True.
  2. Key Presence: The pattern checks if all keys defined in the case statement exist in the subject.
  3. Value Destructuring: If the keys exist, the pattern evaluates the corresponding values against the provided value_pattern.
  4. Partial Matching: Unlike sequence patterns, mapping patterns are partial by default. If the subject contains keys not specified in the pattern, the match will still succeed.

Syntax Variations and Visualization

Basic Key-Value Matching and Binding Values can be matched against literals, types, or bound to variables for use within the case block.
subject = {"status": 200, "data": {"items": [1, 2]}, "timestamp": 1630000000}

match subject:
    case {"status": 200, "data": payload}:
        # Matches if subject is a mapping containing "status" == 200 
        # and a "data" key. The value of "data" is bound to 'payload'.
        print(payload)  # Output: {'items': [1, 2]}
Nested Mapping Patterns Mapping patterns can be nested arbitrarily deep to destructure complex, multi-level dictionaries. When matching built-in types (such as int, str, float, and bool), the pattern matching engine treats them as special cases that accept a single positional sub-pattern. This allows you to validate the type and bind the value simultaneously using syntax like int(uid).
subject = {"user": {"id": 42, "credentials": {"role": "admin"}}, "active": True}

match subject:
    case {"user": {"id": int(uid), "credentials": {"role": "admin"}}}:
        # Matches if subject["user"]["id"] is an integer (bound to uid)
        # and subject["user"]["credentials"]["role"] is exactly "admin".
        print(uid)  # Output: 42
Capturing Remaining Keys (** Unpacking) You can capture all unspecified key-value pairs into a new dictionary using the double-asterisk prefix.
subject = {"route": "/home", "page": 1, "sort": "asc"}

match subject:
    case {"route": "/home", **query_params}:
        # Matches if "route" is "/home". 
        # All other keys in the mapping are packed into the 'query_params' dict.
        print(query_params)  # Output: {'page': 1, 'sort': 'asc'}

Technical Constraints

  • Key Restrictions: Keys within the pattern must be literal patterns (e.g., strings, numbers, booleans, None) or value patterns (e.g., Enum members accessed via dotted names). You cannot use bare variables to dynamically match keys, as bare variables are treated as capture patterns.
class Config:
    NAME_KEY = "name"

subject = {"name": "Alice"}
dynamic_key = "name"

# INVALID: Cannot use a bare variable as a key pattern.
# This raises a SyntaxError at compile time.
# match subject:
#     case {dynamic_key: value}: 
#         pass

# VALID: Using a dotted name constant
match subject:
    case {Config.NAME_KEY: value}:
        print(value)  # Output: Alice

# VALID: Using a literal string
match subject:
    case {"name": value}:
        print(value)  # Output: Alice
  • Duplicate Keys: Defining duplicate keys within a single mapping pattern raises a SyntaxError at compile time.
  • Single Unpacking: Only one ** binding is permitted per mapping pattern, and it must be the final item in the pattern definition.
  • No **_ Wildcard: While **rest is valid for capturing remaining items, using **_ to explicitly ignore remaining items is a SyntaxError. Because mapping patterns are partial by default, **_ is redundant.
Master Python with Deep Grasping Methodology!Learn More