The goal is to write a decorator that updates one keyword argument of the wrapped function.
In the following code wrapper attempts to update kwarg1:
import inspect [0/300678]
from functools import wraps
def override_me(arg, kwarg1="default kwarg1", kwarg2="default kwarg2"):
print(f"override_me {arg} kwarg1={kwarg1} kwarg2={kwarg2}")
def append_kwarg1(func):
original_kwarg1_default = (
inspect.signature(func).parameters["kwarg1"].default
)
@wraps(func)
def wrapper(*args, kwarg1=original_kwarg1_default, **kwargs):
func(*args, kwarg1=kwarg1 + "_patched!", **kwargs)
return wrapper
override_me = append_kwarg1(override_me)
override_me("passed_arg")
override_me("passed_arg", kwarg1="passed_kwarg1_named")
override_me("passed_arg", "passed_kwarg1_as_arg") # TypeError: override_me() got multiple values for argument 'kwarg1'
This, however, fails when kwarg1 is passed as a positional argument.
Edit:
Clarifications as pointed in comments: override_me signature cannot be changed (think: external module).