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
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
Share
Improve this question
asked 2 days ago
Qba23Qba23
111 silver badge2 bronze badges
New contributor
Qba23 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
2 Answers
Reset to default 3case 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
, andstep
, - and match those attributes against patterns
0
,y
, and1
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.
Python's range()
function and the match
statement treat ranges differently. You create a range
using range(start, stop, step)
(only positional arguments). But when you match a range in a case
statement, you must use case range(start=x, stop=y, step=z)
. It's a weird quirk, but that's how it works. Don't try to use other keyword names or positional arguments in the case
– it won't work.