[issue46761] functools.update_wrapper breaks the signature of functools.partial objects

Ofey Chan report at bugs.python.org
Wed Feb 23 10:57:53 EST 2022


Ofey Chan <ofey206 at gmail.com> added the comment:

I fix the problem.

But sorry for my last message, because it totally miss the point ;)

In `inspect.signature()`, the order of handle `follow_wrapper_chains` and `functools.partial` cause the problem.

Relevant code: https://github.com/python/cpython/blob/288af845a32fd2a92e3b49738faf8f2de6a7bf7c/Lib/inspect.py#L2408

The original order is:

1. `follow_wrapper_chains` unwrap decorators.
   - It would check `__wrapped__` attribute in `unwrap()`.
   - `functools.update_wrapper()` would set `__wrapped__`.
2. Then handle `functools.partial`, construct new signature with `_signature_get_partial()`

So the original `functools.partial` object would skip (1), goto (2) and would be correctly processed.

But after calling `functools.update_wrapper()`, the `functools.partial` object has a `__wrapped__` attribute, so it directly handled by (1) and will never reach (2). That's why `inspect.signature()` return the original function's signature.

`update_wrapper.breaks.partial.signature.check.__wrapped__.py` shows the `__wrapped__` attribute.

My solution is simple: swap the order of (1) and (2).

`functools.partial` is a special type of wrapper, handle it before going down the wrapper chain is sane.

And I have written test case to ensure it's correct, hope it works.

----------

_______________________________________
Python tracker <report at bugs.python.org>
<https://bugs.python.org/issue46761>
_______________________________________


More information about the Python-bugs-list mailing list