Skip to content

Improve SyntaxError message for inconsistent name binding in OR-patterns #145019

Closed

Description

@Sriiishtiiiii

Feature or enhancement

Proposal:

Title

compiler: improve SyntaxError message for inconsistent name binding in OR-patterns

Summary

When using structural pattern matching (PEP 634), all alternatives of an OR-pattern (|) are required to bind the same set of names.

Currently, if this rule is violated, CPython raises a SyntaxError with the message:

SyntaxError: alternative patterns bind different names

While technically correct, this message does not indicate which names differ or how the bindings are inconsistent.

This issue proposes enhancing the diagnostic to explicitly report the mismatched bindings.

Reproducer

match value:
    case 1 | x:
        pass

Output:

SyntaxError: alternative patterns bind different names

The message does not clarify:

  • Which variable(s) are inconsistently bound
  • Which alternative introduces additional bindings
  • What the required constraint is

Expected Behavior

The error message should clearly indicate the binding mismatch. For example:

SyntaxError: OR-pattern alternatives must bind the same names;
left alternative binds no names, right alternative binds {'x'}

or:

SyntaxError: inconsistent variable binding in OR-pattern: 'x' is not bound in all alternatives

The exact wording can be adjusted, but the diagnostic should identify the differing name(s).

Rationale

PEP 634 specifies that all OR-pattern alternatives must bind identical sets of names.

Providing more detailed diagnostics would:

  • Improve developer experience
  • Make the rule easier to understand
  • Align with recent improvements in CPython error reporting
  • Maintain consistency with Python’s philosophy of helpful error messages

Scope

  • No syntax changes
  • No semantic changes
  • No AST changes
  • Diagnostic enhancement only

Implementation Notes

The relevant validation logic appears to occur during semantic analysis of pattern matching (likely in Python/ast.c or related compiler validation code).

The change would involve augmenting the existing name-set comparison logic to include information about the differing bindings in the raised SyntaxError.

Backward Compatibility

This change affects only the wording of an error message and does not alter runtime behavior.

Tests

Regression tests can be added to Lib/test/test_patma.py to assert that the improved diagnostic includes information about mismatched variable names.

Has this already been discussed elsewhere?

This is a minor feature, which does not need previous discussion elsewhere

Links to previous discussion of this feature:

No response

Linked PRs

Activity

  1. picnixz commented on Feb 20, 2026

    @picnixz
    Member

    I'd say it's nice to have unless it adds complexity in the parser/lexer/compiler/whatever (I don't remember where this message would be emitted).

    However, what is more important is to have real use-cases where such messages would be useful. Having such message in 1 | x doesn't really seem useful IMO (the snippet is short enough). It's more useful if we are constructing a complex pattern matching.

  2. Sriiishtiiiii commented on Mar 4, 2026

    @Sriiishtiiiii
    Author

    You're right @picnixz, the example in the issue is quite small. The situation where this could be more helpful is when the OR-patterns are part of a larger or nested match statement.

    For example:

    match value:
        case ("user", {"id": id}) | ("admin", {"name": name}):
            process(id)

    This currently raises:

    SyntaxError: alternative patterns bind different names
    

    But from the message alone it's not immediately clear which bindings are different. In this case the left alternative binds id while the right binds name.

    In larger patterns or when refactoring code, it can take a bit of time to spot which variable caused the mismatch. Having the diagnostic mention the differing names could make the error easier to understand.

    The goal would just be to improve the diagnostic without changing semantics.

  3. picnixz commented on Mar 4, 2026

    @picnixz
    Member

    I see, for the dicts it does make sense, at least to help debugging. FTR, the location to change would be

    _PyCompile_Error(c, LOC(p), "alternative patterns bind different names");

    but we actually don't compute the names that are incorrect. Changing this function may be tricky but I can try this w-e to see whether the change is small. I do see value in indicating the bad names, but it would only be helpful when your patterns are not numerous. If you have multiple OR patterns, deciding which one is the correct and which one is not would be annoying. But something like:

    SyntaxError: alternative pattern bind different names (first mismatch: group N, unexpected names: {...})

    I don't know whether I'll be able to pinpoint the exact pattern so that we also have relevant ^^--- symbols.

  4. self-assigned this
    on Mar 5, 2026
  5. added 2 commits that reference this issue on Mar 14, 2026
  6. picnixz commented on Mar 14, 2026

    @picnixz
    Member

    So the implementation wasn't that hard. The error message is now:

    SyntaxError: alternative patterns bind different names (first pattern binds no names, pattern 2 binds ['x'])

    so that you know which pattern is incorrect (well you still need to count them but it's the same when you have a function call and one of your argument that doesn't have a name is wrong).

  7. removed their assignment
    on Mar 28, 2026
  8. Sriiishtiiiii commented on Apr 2, 2026

    @Sriiishtiiiii
    Author

    nice improvement.... making the binding set explicit removes a lot of the guesswork when diagnosing or-pattern inconsistencies, particularly in complex pattern trees.

  9. added a commit that references this issue on Oct 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    interpreter-core(Objects, Python, Grammar, and Parser dirs)type-featureA feature request or enhancement

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions