def optional_args_func(func) -> callable:
if getattr(func, '<STR_LIT>', False):<EOL><INDENT>return func<EOL><DEDENT>is_generator = inspect.isgeneratorfunction(func)<EOL>func_sig = inspect.signature(func)<EOL>expects_nothing = not func_sig.parameters<EOL>if is_generator:<EOL><INDENT>@functools.wraps(func)<EOL>def wrapped(*args, **kwargs):<EOL><INDENT>if expects_nothing:<EOL><INDENT>yield from func()<EOL><DEDENT>else:<EOL><INDENT>bound_arguments = func_sig.bind(*args, **{k: v for k, v in kwargs.items() if k in func_sig.parameters})<EOL>yield from func(*bound_arguments.args, **bound_arguments.kwargs)<EOL><DEDENT><DEDENT><DEDENT>else:<EOL><INDENT>@functools.wraps(func)<EOL>def wrapped(*args, **kwargs):<EOL><INDENT>if expects_nothing:<EOL><INDENT>return func()<EOL><DEDENT>else:<EOL><INDENT>bound_arguments = func_sig.bind(*args, **{k: v for k, v in kwargs.items() if k in func_sig.parameters})<EOL>return func(*bound_arguments.args, **bound_arguments.kwargs)<EOL><DEDENT><DEDENT><DEDENT>setattr(wrapped, '<STR_LIT>', True)<EOL>return wrapped<EOL>
Given a function or generator `func`, return a function/generator
that takes any number of kwargs and calls `func` with only the args/kwargs
that `func` expects.