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
Changed behavior of <instancemethod>.__get__ in Python 3.11 #113157
There is a change in behavior in Python 3.11 that does not seem to be described in the "what's new" document.
In the following code:
classA:
defmeth(self):
print(self)
classB:
passa=A()
b=B()
b.meth=a.meth.__get__(b, B)
b.meth()
The b.meth() call receives a as the self argument up to Python 3.10, but b in 3.11 and 3.12.
This pattern is used by the Pyramid framework. The change breaks Pyramid applications that use add_request_method(someobject.somemethod, "name").
I have to admit that I do not understand the descriptor protocol (or the documentation of __get__) well enough to say whether this is a legitimate use case, but it does exist in the wild.
@MarcSchmitzer is correct and the "return a" behavior should be restored.
For Python 3.13, this is straightforward. Since classmethod descriptor chaining has now been removed, we can just add back method_descr_get to PyMethod_Type.
For Python 3.11 and Python 3.12, the situation is more complex and we can't fix any one aspect of the problem without breaking something else. Here are the options that come to mind:
Leave Python 3.11 and 3.12 as-is. But that would be a problem for the Pyramid framework.
Apply the 3.13 solution to 3.11 and 3.12. This is the cleanest way in the sense that we will have fully restored the original long-standing behaviors before the classmethod descriptor chaining trainwreck began. However, this path breaks having classmethod wrap property which is something that we know people use — that is why we went through a deprecation period to finally remove it in 3.13.
Activity
Eclips4 commentedon Dec 15, 2023
Bisected to a918589
cc @msullivan @rhettinger
rhettinger commentedon Dec 17, 2023
@MarcSchmitzer is correct and the "return a" behavior should be restored.
For Python 3.13, this is straightforward. Since classmethod descriptor chaining has now been removed, we can just add back
method_descr_gettoPyMethod_Type.For Python 3.11 and Python 3.12, the situation is more complex and we can't fix any one aspect of the problem without breaking something else. Here are the options that come to mind:
classmethodwrappropertywhich is something that we know people use — that is why we went through a deprecation period to finally remove it in 3.13.pythongh-113157 pythongh-89519 Restore behaviors before classmethod d…
rhettinger commentedon Dec 19, 2023
@msullivan Would you be okay with reverting a918589 ? We wouldn't have gone down that path had we known that it would break another part of the API.
rhettinger commentedon Dec 21, 2023
For 3.11 and 3.12, I suggest that we revert a918589
Any objections?
gh-113157 gh-89519: Fix method descriptors (gh-113233)
erlend-aasland commentedon Dec 22, 2023
cc. @pablogsal as 3.11 RM, and @Yhg1s as 3.12 RM.
gh-89519 & gh-113157 (Remove classmethod descriptor chaining, depreca…
pythongh-113157 pythongh-89519: Fix method descriptors (pythongh-113233)
pythongh-113157 pythongh-89519: Fix method descriptors (pythongh-113233)
pythongh-113157 pythongh-89519: Fix method descriptors (pythongh-113233)
pythongh-113157: Document and test __get__ for MethodType
gh-113157: Document and test __get__ for MethodType (gh-115492)
pythongh-113157: Document and test __get__ for MethodType (pythongh-1…
pythongh-113157: Document and test __get__ for MethodType (pythongh-1…
pythongh-113157 pythongh-89519: Fix method descriptors (pythongh-113233)
pythongh-113157: Document and test __get__ for MethodType (pythongh-1…