python-makefun icon indicating copy to clipboard operation
python-makefun copied to clipboard

Inconsistency in behavior of `functools.partial` and `makefun.partial`

Open elchupanebrej opened this issue 2 years ago • 1 comments

There is function

def func(a):
    print(f"Arg: {a}")

When it is used by functiools.partial:

from functools import partial

partial(partial(func, a=1), a=2)()
"""
>>> Arg: 2
"""

When it is used by makefun.partial:

from makefun import partial as mpartial

mpartial(mpartial(func, a=1), a=2)()
"""
>>> Arg: 1
"""

So makefun.partial could not be drop-in replacement for functools.partial

elchupanebrej avatar Jul 10 '23 11:07 elchupanebrej

Nice finding @elchupanebrej !!

I was not aware that partial could be used to modify assignments already done by a nested partial.

So makefun.partial could not be drop-in replacement for functools.partial

Well, in most applications it can be, as the usage you mention is extremely rare :)

If you would like to propose something, I am open to a PR modifying partial to

  • detect that f is an already partialized function (by us). We can rely on the existence of the func attribute but this is not enough.
  • update the dict in the appropriate closure if this is the case, rather than re-partialize it

Note that storing the preset_kwargs outside of the closure (i.e. on an explicit attribute on the function) could be a solution, but I have not enough knowledge of python internals to be sure that this would not impact performance or have side-effects...

smarie avatar Nov 09 '23 22:11 smarie