Repository navigation
Behaviour change in partialmethod in Python3.11 #99152
Description
Activity
- addedtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
on Nov 6, 2022 I bisected to here:
a918589 is the first bad commit
commit a918589
Author: Michael J. Sullivan sully@msully.net
Date: Wed May 4 21:00:21 2022 -0700bpo-46764: Fix wrapping bound method with @classmethod (#31367)cc @rhettinger
Having stumbled across this in a Django app where I was using
Field.contribute_to_classto add some extra functionality to models that I couldn't change directly, I experimented with a few different workarounds with very little success.
Eventually I decided the easiest solution was an explicit decorator, and this is what I'm using now (in the very specific cases where I need to ensure the old behavior is maintained:class partialmethod_with_self(partialmethod): def __get__(self, obj, cls=None): return self._make_unbound_method().__get__(obj, cls)This works in my case, and it should be backwards-compatible as well (I tested against 3.11 and 3.9.2).
Reacted by Niko Savola, Guang Yang and samim-sn- addedstdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directory
on Nov 26, 2023 Is this behavior change documented anywhere? Will it ever be fixed? Is it considered as a bug at all by the python devs?
I am also being hit by this problem in the context of django (and the
contribute_to_classpattern). This basically boils down to this snippet (works fine until 3.10, errors out in 3.11 and 3.12):from functools import partialmethod class A: @classmethod def f1(cls, self, value): self.value = value class B: def __init__(self): self.value = None setattr(B, 'set_value_true', partialmethod(A.f1, True)) b = B() b.set_value_true() print(b.value)
Bug report
The behavior of
partialmethodchanged in python3.11. This caused a library that I use testsuite to fail.Here is a minimal use case that demonstrates this:
In python3.10, this prints
True. In python3.11 it errors with:The arguments passed to
Wrapper.set_state_wrapare:python3.10:
wrapper, cell, Truepython3.11:
cell, TrueSo
partialmethodis forgetting thatset_state_wrapis a method ofwrapper, and it needs to pass that in as the first arg.I know that the way that they are using
partialmethodhere is not how it is intended to be used, and feels wrong. However this change is behavior if intended should be documented.Your environment