Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Point() accepts 0 positional sub-patterns (2 given)

I'm trying to run an example from the docs, but get the error:

Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
TypeError: Point() accepts 0 positional sub-patterns (2 given)

Can someone explain what I doing wrong here?

class Point():
    def __init__(self, x, y):
            self.x = x
            self.y = y

x, y = 5 ,5
point = Point(x, y)
match point:
    case Point(x, y) if x == y:
        print(f"Y=X at {x}")
    case Point(x, y):
        print(f"Not on the diagonal")
like image 214
HelgiBergmann Avatar asked Jun 13 '26 02:06

HelgiBergmann


1 Answers

You need to define __match_args__ in your class. As pointed at in this section of the "What's new in 3.10" page:

You can use positional parameters with some builtin classes that provide an ordering for their attributes (e.g. dataclasses). You can also define a specific position for attributes in patterns by setting the __match_args__ special attribute in your classes. If it’s set to (“x”, “y”), the following patterns are all equivalent (and all bind the y attribute to the var variable):

Point(1, var)
Point(1, y=var)
Point(x=1, y=var)
Point(y=var, x=1)

So your class will need to look as follows:

class Point:
    __match_args__ = ("x", "y")
    def __init__(self, x, y):
        self.x = x
        self.y = y

Alternatively, you could change your match structure to the following:

match point:
    case Point(x=x, y=y) if x == y:
        print(f"Y=X at {x}")
    case Point(x=x, y=y):
        print(f"Not on the diagonal")

(Note that you don't need a both: a class with __match_args__ defined, does not need to have its arguments specified in the match-case statements.)

For full details, I'll refer readers to PEP 634, which is the specification for structural pattern matching. The details on this particular point are in the section Class Patterns.

For a better introduction or tutorial, don't use the "What's New" documentation, as it tends to provide an overview, but may skip over some things. Instead, use PEP 636 -- Structural Pattern Matching: Tutorial, or the language reference on match statements for more details.


It is mentioned in the quoted text that a dataclass will already have an ordering, and in your example, a dataclass also works fine:

from dataclasses import dataclass

@dataclass
class Point:
    x: int
    y: int

x, y = 5, 5
point = Point(x, y)

match point:
    case Point(x, y) if x == y:
        print(f"Y=X at {x}")
    case Point(x, y):
        print(f"Not on the diagonal")
like image 181
9769953 Avatar answered Jun 15 '26 16:06

9769953



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!