Python quirk: Signatures are evaluated at import time

  • 21 July, 2016

Every Python programmer knows to avoid mutable default arguments:

def fn(mutable=[]):
    mutable.append('elem')
    print mutable

fn()
fn()
$ python test.py
['elem']
['elem', 'elem']

However, many are not clear that this is due to arguments being evaluated at import time, rather than the first time the function is evaluated.

This results in related quirks such as:

def never_called(error=1/0):
    pass
$ python test.py
Traceback (most recent call last):
  File "test.py", line 1, in <module>
ZeroDivisionError: integer division or modulo by zero

... and an—implementation-specific—quirk caused by naive constant folding:

def never_called():
    99999999 ** 9999999
$ python test.py
[hangs]

I suspect that this can be used as denial-of-service vector.