import inspect
from types import FunctionType
def ensure_kwargs(func):
if func.__code__.co_flags & inspect.CO_VARKEYWORDS:
return func
return FunctionType(
code=func.__code__.replace(
co_flags=func.__code__.co_flags | inspect.CO_VARKEYWORDS,
co_varnames=func.__code__.co_varnames + ('kwargs',),
co_nlocals=func.__code__.co_nlocals + 1
),
globals=func.__globals__,
name=func.__name__,
argdefs=func.__defaults__,
closure=func.__closure__
)
def test1(x, z=1, **kwargs):
print(f'{x=}, {z=}, {kwargs=}')
def test2(x, y=1):
print(f'{x=}, {y=}')
def test3(x, y=1, z=1):
print(f'{x=}, {y=}, {z=}')
def call_center(**kwargs):
for test in tests:
test(**kwargs)
tests = list(map(ensure_kwargs, [test1, test2, test3]))
call_center(x=1, y=2)
call_center(x=3, z=4)
aW1wb3J0IGluc3BlY3QKZnJvbSB0eXBlcyBpbXBvcnQgRnVuY3Rpb25UeXBlCgpkZWYgZW5zdXJlX2t3YXJncyhmdW5jKToKICAgIGlmIGZ1bmMuX19jb2RlX18uY29fZmxhZ3MgJiBpbnNwZWN0LkNPX1ZBUktFWVdPUkRTOgogICAgCXJldHVybiBmdW5jCiAgICByZXR1cm4gRnVuY3Rpb25UeXBlKAogICAgICAgIGNvZGU9ZnVuYy5fX2NvZGVfXy5yZXBsYWNlKAogICAgICAgICAgICBjb19mbGFncz1mdW5jLl9fY29kZV9fLmNvX2ZsYWdzIHwgaW5zcGVjdC5DT19WQVJLRVlXT1JEUywKICAgICAgICAgICAgY29fdmFybmFtZXM9ZnVuYy5fX2NvZGVfXy5jb192YXJuYW1lcyArICgna3dhcmdzJywpLAogICAgICAgICAgICBjb19ubG9jYWxzPWZ1bmMuX19jb2RlX18uY29fbmxvY2FscyArIDEKICAgICAgICApLAogICAgICAgIGdsb2JhbHM9ZnVuYy5fX2dsb2JhbHNfXywKICAgICAgICBuYW1lPWZ1bmMuX19uYW1lX18sCiAgICAgICAgYXJnZGVmcz1mdW5jLl9fZGVmYXVsdHNfXywKICAgICAgICBjbG9zdXJlPWZ1bmMuX19jbG9zdXJlX18KICAgICkKCmRlZiB0ZXN0MSh4LCB6PTEsICoqa3dhcmdzKToKICAgIHByaW50KGYne3g9fSwge3o9fSwge2t3YXJncz19JykKZGVmIHRlc3QyKHgsIHk9MSk6CiAgICBwcmludChmJ3t4PX0sIHt5PX0nKQpkZWYgdGVzdDMoeCwgeT0xLCB6PTEpOgogICAgcHJpbnQoZid7eD19LCB7eT19LCB7ej19JykKCmRlZiBjYWxsX2NlbnRlcigqKmt3YXJncyk6CiAgICBmb3IgdGVzdCBpbiB0ZXN0czoKICAgICAgICB0ZXN0KCoqa3dhcmdzKQp0ZXN0cyA9IGxpc3QobWFwKGVuc3VyZV9rd2FyZ3MsIFt0ZXN0MSwgdGVzdDIsIHRlc3QzXSkpCmNhbGxfY2VudGVyKHg9MSwgeT0yKQpjYWxsX2NlbnRlcih4PTMsIHo9NCk=
x=1, z=1, kwargs={'y': 2}
x=1, y=2
x=1, y=2, z=1
x=3, z=4, kwargs={}
x=3, y=1
x=3, y=1, z=4