Thor Whalen <thorwhal...@gmail.com> added the comment:
Further, note that even with the additional '__defaults__', and '__kwdefaults__', `functools.wraps` breaks when keyword only arguments involved: ``` from functools import wraps, WRAPPER_ASSIGNMENTS, partial # First, I need to add `__defaults__` and `__kwdefaults__` to wraps, because they don't come for free... my_wraps = partial(wraps, assigned=(list(WRAPPER_ASSIGNMENTS) + ['__defaults__', '__kwdefaults__'])) def g(a: float, b=10): return a * b def f(a: int, *, b=1): return a * b # all is well (for now)... assert f(3) == 3 assert g(3) == 30 ``` This: ``` my_wraps(g)(f)(3) ``` raises TypeError (missing required positional argument 'b'), expected Note that `wraps(g)(f)(3)` doesn't throw a TypeError, but the output is not consistent with the signature (inspect.signature(wraps(g)(f)) is (a: float, b=10), so 3 should be multiplied by 10). This is because __defaults__ wasn't updated. See for example, that third-party from boltons.funcutils import wraps works as expected. And so do (the very popular) wrapt and decorator packages. Boltons works for wraps(f)(g), but not wraps(g)(f) in my example. See: https://stackoverflow.com/questions/62782709/pythons-functools-wraps-breaks-when-keyword-only-arguments-involved ---------- _______________________________________ Python tracker <rep...@bugs.python.org> <https://bugs.python.org/issue41232> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com