how to fix TypeError: called match pattern must be a type in Python 3.10
Asked Answered
F

3

8

Trying to learn Python 3.10 pattern matching. Tried this example after reading 8.6.4.9. Mapping Patterns

>>> match 0.0:
...  case int(0|1):
...   print(1)
...
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
TypeError: called match pattern must be a type
>>>

Especially the note on built-in types, including int. How should I code to test for an integer value of 0 or 1 (the example in the doc) and not get this error?

Face answered 10/11, 2021 at 18:43 Comment(1)
I cannot reproduce the error. Executing your exact lines on a Python 3.10 console does not print anything. Then, changing 0.0 to 0 or 1 prints 1. I'm unsure how you got that error, your code should work fine.Hectograph
F
7

I fell into a gotcha:

match 0.0
  case int:
    print(1)

effectively redefines int, so the next time I tried the match I posted, it failed since my int was shadowing the built in

Face answered 19/11, 2021 at 21:17 Comment(1)
Ughh that makes it seem like it's just waiting to introduce hard-to-debug problems.Abeyance
M
6

For structural pattern matching, the class pattern requires parentheses after the class name.

For example:

x = 0.0
match x:
    case int():
        print('I')
    case float():
        print('F')
    case _:
        print('Other')
Morphophoneme answered 1/3, 2022 at 19:44 Comment(1)
You're not putting parentheses around any class name. What did you mean?Kathikathiawar
R
1

How should I code to test for an integer value of 0 or 1

The right answer is to use OR-Patterns, described in PEP 622:

Multiple alternative patterns can be combined into one using |. This means the whole pattern matches if at least one alternative matches. Alternatives are tried from left to right and have a short-circuit property, subsequent patterns are not tried if one matched.

x = 1
match x:
    case int(0 | 1):
        print('case of x = int(0) or x = int(1)')
    case _:
        print('x != 1 or 0')

Output: 'case of x = int(0) or x = int(1)'

Type insensitive would be like this:

x = 1.0
match x:
    case 0 | 1:
        print('case of x = 0 or x = 1')
    case _:
        print('x != 1 or 0')

Output: 'case of x = 0 or x = 1'


In case you want to check for each case separately, you would do:

x = 1.0
match x:
    case int(0):
        print('x = 0')
    case int(1):
        print('x = 1')
    case _:
        print('x != 1 or 0')

Output: x != 1 or 0

x = 1.0
match x:
    case 0:
        print('x = 0')
    case 1:
        print('x = 1')
    case _:
        print('x != 1 or 0')

Output: x = 1

Retina answered 13/3, 2022 at 10:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.