In the docs for randrange()
, it states:
Keyword arguments should not be used because they can be interpreted in unexpected ways. For example
randrange(start=100)
is interpreted asrandrange(0, 100, 1)
.
If the signature is random.randrange(start, stop[, step])
, why doesn't randrange(start=100)
raise an error, since stop
is not passed a value?
Why would randrange(start=100)
be interpreted as randrange(0, 100, 1)
?
I'm not trying to understand the design choice of whoever wrote the code, so much as understanding how it's even possible. I thought parameters without default values need to be passed arguments or else a TypeError would be raised.
This is because the code for randrange
must also support the alternative signature:
random.randrange(stop)
The implementation performs a check to see whether the call uses this signature or the other one:
random.randrange(start, stop[, step])
It does so with this code:
istart = _index(start)
if stop is None:
if istart > 0:
return self._randbelow(istart)
This makes sense when you call randrange(100)
, where it translates into a call of _randbelow(100)
, which is intended.
But when you call randrange(start=100)
, then we get into the same flow, and the value of start
is also interpreted as stop
.