How can Walrus patterns work in Pattern Matching

PEP 622 – Structural Pattern Matching#walrus-patterns | peps.python.org

from dataclasses import dataclass

@dataclass
class Point:
    x: int
    y: int

@dataclass
class Line:
    p1: Point
    p2: Point

match Line(Point(1,2), Point(3,4)):
    case Line(start := Point(x, y), end) if start == end:
        print(f"Zero length line at {x}, {y}")

the code run in Python 3.12.1, but it cannot work.

    case Line(start := Point(x, y), end) if start == end:
                    ^^
SyntaxError: invalid syntax
>>> from dataclasses import dataclass
>>>
>>> @dataclass
... class Point:
...     x: int
...     y: int
...
>>> @dataclass
... class Line:
...     p1: Point
...     p2: Point
...
>>> match Line(Point(1,2), Point(3,4)):
...     case Line(start, end) if (start := Point(x,y)) == end:
...             print(f'Zero length line at {x}, {y}')
...

You need to use the walrus in the if.

PEP-622 is not the correct PEP to look at, it’s superseded by PEP-634/5/6.

The syntax that actually got implemented is case Line(Point(x, y) as start, end) if start == end:

1 Like
case Line(start, end) if (start := Point(x,y)) == end:

In what Python version does that work?

>>> import sys
>>> sys.version
'3.10.10 (v3.10.10:aad5f6a891, Feb  7 2023, 08:47:40) [Clang 13.0.0 (clang-1300.0.29.30)]'

3.10 apparently.

I was a bit surprised that it didn’t trigger a different issue but I knew it would resolve the improper placement of the walrus operator one.

Thanks for your help, it works now.

1 Like

I don’t believe it. Probably you didn’t actually try (just) that code. I get a NameError for x in 3.10 as well.


I ran the code to make sure it worked.

And the first two lines in that screenshot prove that you did not just try that code but had run other code before (which likely defined x and y).

Yes it wasn’t a new REPL instance. And apparently I had x and y defined in it. However, the NameError that is encountered is irrelevant - the SyntaxError was the issue.

It’s not irrelevant if that makes it not work.