+0.x for a new keyword that adds dynamic semantics (and removes the need for the sentinel kludge).
import copy
def clone_arguments(f):
default_args = list(f.func_defaults)
if len(default_args) < f.func_code.co_argcount:
delta = f.func_code.co_argcount - len(default_args)
default_args = ([None] * delta) + default_args
def fn(*args):
if len(args) < default_args:
args = args + tuple(copy.deepcopy(default_args[len(args):]))
return f(*args)
return fn
@clone_arguments
def thing_taking_array(a, b = []):
b.append(a)
return b
print thing_taking_array('123')
print thing_taking_array('abc')