pythonparameter-passing

Why doesn't `randrange(start=100)` raise an error?


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 as randrange(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.


Solution

  • 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.