Re:Strict Python function parameters
by dragonwriter on Sunday January 23, 2022 @03:16PM
(#30050029)
> Maybe you could make a function decorator that looked for a special type of default value
If you make the functions to supply late-bound defaults arguments to the decorator, its pretty doable; here’s what I just threw together.
from inspect import signature, Parameter
def with_deferred_defaults(*args, **kwargs):
def decorate(fun):
parameters = signature(fun).parameters
positional_parameters = [parameter for parameter in parameters.values() if parameter.kind in [Parameter.POSITIONAL_ONLY, Parameter.POSITIONAL_OR_KEYWORD]]
defaults = list(args)
kwdefaults = kwargs
def wrapper(*args, **kwargs):
args = list(args)
if len(args) < len(defaults):
args = args + [arg() for arg in defaults[len(args):]]
new_kwargs = {k: v() for k, v in kwdefaults.items()}
new_kwargs.update(kwargs)
for i, p in enumerate(positional_parameters):
if i >= len(args):
if p.name in new_kwargs:
args.extend([None]*(1+i-len(args)))
args[i] = new_kwargs[p.name]
del new_kwargs[p.name]
elif p.default is Parameter.empty:
raise TypeError('Missing argument: {}'.format(p.name))
else:
if p.name in new_kwargs:
del new_kwargs[p.name]
return fun(*args, **new_kwargs)
return wrapper
return decorate
If you make the functions to supply late-bound defaults arguments to the decorator, its pretty doable; here’s what I just threw together.