Author Thor Whalen2
Recipients Thor Whalen2
Date 2020-07-07.22:18:12
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1594160292.87.0.489171460639.issue41232@roundup.psfhosted.org>
In-reply-to
Content
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
History
Date User Action Args
2020-07-07 22:18:12Thor Whalen2setrecipients: + Thor Whalen2
2020-07-07 22:18:12Thor Whalen2setmessageid: <1594160292.87.0.489171460639.issue41232@roundup.psfhosted.org>
2020-07-07 22:18:12Thor Whalen2linkissue41232 messages
2020-07-07 22:18:12Thor Whalen2create