You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Behaviour change in partialmethod in Python3.11 #99152
In python3.10, this prints True. In python3.11 it errors with:
Traceback (most recent call last):
File "/home/gary/partialmethod.py", line 23, in <module>
c.set_alive()
TypeError: Wrapper.set_state_wrap() missing 1 required positional argument: 'state'
The arguments passed to Wrapper.set_state_wrap are: python3.10: wrapper, cell, True python3.11: cell, True
So partialmethod is forgetting that set_state_wrap is a method of wrapper, and it needs to pass that in as the first arg.
I know that the way that they are using partialmethod here is not how it is intended to be used, and feels wrong. However this change is behavior if intended should be documented.
Your environment
CPython versions tested on: Python 3.11.0 (broken) Python 3.10.7 (working)
Operating system and architecture: Fedora Linux 36
Having stumbled across this in a Django app where I was using Field.contribute_to_class to 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).
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_class pattern). 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)
Activity
sweeneyde commentedon Nov 6, 2022
I bisected to here:
sweeneyde commentedon Nov 6, 2022
cc @rhettinger
pgcd commentedon Dec 18, 2022
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:
This works in my case, and it should be backwards-compatible as well (I tested against 3.11 and 3.9.2).
goffioul commentedon Sep 25, 2024
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):duaneg commentedon May 22, 2025
This was fixed in d058eae for #113157 (which is effectively a dup of this, I think) and delivered in v.3.13.0.
I believe this issue can be closed.
fix python 3.13+ compat