1

All examples tested using Python 3.13.2 on Windows 10.

When calling range(), I must use positional arguments, or otherwise I get an exception.

>>> range(2, 5)
range(2, 5)
>>> range(start=2, stop=5)
Traceback (most recent call last):
  File "<python-input-1>", line 1, in <module>
    range(start=2, stop=5)
    ~~~~~^^^^^^^^^^^^^^^^^
TypeError: range() takes no keyword arguments

However, when trying to match pattern, it only works with keyword arguments instead.

>>> match range(2, 5):
...     case range(0, y, 1):
...         print('1 argument')
...     case range(x, y, 1):
...         print('2 arguments')
...     case range(x, y, z):
...         print('3 arguments')
...     case _:
...         print('none of the above')
...
Traceback (most recent call last):
  File "<python-input-0>", line 2, in <module>
    case range(0, y, 1):
         ~~~~~^^^^^^^^^
TypeError: range() accepts 0 positional sub-patterns (3 given)
>>> match range(2, 5):
...     case range(start=0, stop=y, step=1):
...         print('1 argument')
...     case range(start=x, stop=y, step=1):
...         print('2 arguments')
...     case range(start=x, stop=y, step=z):
...         print('3 arguments')
...     case _:
...         print('none of the above')
...
2 arguments

Interestingly, those arguments can't just use any arbitrary names. Using different ones causes the pattern match to fail, without raising an exception.

>>> match range(2, 5):
...     case range(aaa=0, bbb=y, ccc=1):
...         print('1 argument')
...     case range(aaa=x, bbb=y, ccc=1):
...         print('2 arguments')
...     case range(aaa=x, bbb=y, ccc=z):
...         print('3 arguments')
...     case _:
...         print('none of the above')
...
none of the above

1 Answer 1

3

case range(start=0, stop=y, step=1): isn't a function call with keyword arguments. It's a class pattern, which has confusingly similar syntax but means something completely different.

The actual meaning of case range(start=0, stop=y, step=1): is

  • match an instance of the range class (yes, that's a class),
  • which has attributes start, stop, and step,
  • and match those attributes against patterns 0, y, and 1 respectively.

0 and 1 are literal patterns, so they'll check that the range's start and step attributes are equal to 0 and 1 respectively. y is a capture pattern, so it'll assign the range's stop attribute to the y variable.

At no point in this process does a class pattern actually care what arguments a class's constructor takes. It only cares about the type and attributes of the object being matched.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.