1
lst = [1, 2, 3]
match lst:
  case list((1, 2, 3)):
    print(2)

gives 2 as output, but,

from fractions import Fraction

frctn = Fraction(1, 2)

match frctn:
  case Fraction(1, 2):
    print(1)

gives,

TypeError: Fraction() accepts 0 positional sub-patterns (2 given)

any specific reasoning for allowing positional sub-patterns for some types while not allowing them for some types?

Brian61354270
  • 8,690
  • 4
  • 21
  • 43
apostofes
  • 2,959
  • 5
  • 16
  • 31
  • 1
    I would try named sub-patterns: `Fraction(numerator=1, denominator=2)`. I'm very new to pattern matching, but my guess would be whether positional or named subpatterns are accepted depends on the `__init__()` declaration of the class. – Code-Apprentice Jun 07 '22 at 14:57
  • Related (maybe a dupe?): https://stackoverflow.com/questions/69627609/point-accepts-0-positional-sub-patterns-2-given – Code-Apprentice Jun 07 '22 at 14:59
  • https://peps.python.org/pep-0636/#matching-positional-attributes the logic seems to be that most classes "don’t have a natural ordering of their attributes" - the pattern match _isn't creating an instance_, so it is not using the order of args to `__init__` method. I guess `list` allows it because it takes a single arg, also because matching sequences is important part of pattern matching functionality https://peps.python.org/pep-0636/#matching-sequences – Anentropic Jun 07 '22 at 15:04
  • @Anentropic Yes, my comment about `__init__()` was incorrect. I posted an update as an actual answer. Also, since sequences have a natural ordering (because they are sequences), it makes sense to match elements by position. – Code-Apprentice Jun 07 '22 at 17:27

1 Answers1

2

Positional subpatterns in a class are declared using the __match_args__ magic attribute. See here for details. It appears that Fraction doesn't declare this attribute, so you must use named subpatterns instead:

Fraction(numerator=1, denominator=2)

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

Code-Apprentice
  • 81,660
  • 23
  • 145
  • 268