News for hackers. Stuff that matters.
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

There are no comments on this comment yet.