Structural pattern matching is a new Python feature released in version 3.10. While reading up on the feature I noticed a curious design choice in class pattern. Take the script below for example.

x = '123'

match x:
  case str():
    print('a string')
  case _:
    print('not a string')

# prints 'a string'

This is interesting because str() is the same syntax for constructing an empty string. Without reading the pattern matching specs one might expect this constructs an empty string and thus case str() is equivalent to case ''. However that is not the case. The parentheses are part of class pattern syntax rather than actual class construction syntax, so no object is constructed in this case. See below the grammar for class pattern. Parenthese are required whenever matching by class is used.

class_pattern:
    | name_or_attr '(' [pattern_arguments ','?] ')'
pattern_arguments:
    | positional_patterns [',' keyword_patterns]
    | keyword_patterns
positional_patterns: ','.pattern+
keyword_patterns: ','.keyword_pattern+
keyword_pattern: NAME '=' pattern

I haven’t found the documentation on why class pattern is designed this way. The reasons I can think of for such design:

  1. The () explicitly differentiates class pattern from capture patterns, which can be any valid variable name. (Explicit is better than implicit. – The Zen of Python)
  2. This maintains a consistent syntax for class pattern with or without arguments, classA(arg1=1) and classA() are both valid class pattern for example.
  3. It’s also a lot easier to implement with the explicit syntax.