Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changed behavior of <instancemethod>.__get__ in Python 3.11 #113157

Open
mschmitzer opened this issue Dec 15, 2023 · 5 comments
Open

Changed behavior of <instancemethod>.__get__ in Python 3.11 #113157

mschmitzer opened this issue Dec 15, 2023 · 5 comments
Assignees
Labels
type-bug An unexpected behavior, bug, or error

Comments

@mschmitzer
Copy link

mschmitzer commented Dec 15, 2023

Bug report

Bug description:

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:

class A:
    def meth(self):
      print(self)

class B:
    pass

a = 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.

CPython versions tested on:

3.9, 3.10, 3.11, 3.12

Operating systems tested on:

Linux

Linked PRs

@mschmitzer mschmitzer added the type-bug An unexpected behavior, bug, or error label Dec 15, 2023
@Eclips4
Copy link
Member

Eclips4 commented Dec 15, 2023

Bisected to a918589
cc @msullivan @rhettinger

@rhettinger rhettinger self-assigned this Dec 17, 2023
@rhettinger
Copy link
Contributor

@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:

  1. Leave Python 3.11 and 3.12 as-is. But that would be a problem for the Pyramid framework.
  2. Revert a918589 . But that would break @msullivan 's use case.
  3. 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.

rhettinger added a commit to rhettinger/cpython that referenced this issue Dec 17, 2023
@rhettinger
Copy link
Contributor

@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
Copy link
Contributor

For 3.11 and 3.12, I suggest that we revert a918589

Any objections?

rhettinger added a commit that referenced this issue Dec 21, 2023
Restore behaviors before classmethod descriptor chaining was introduced.
@erlend-aasland
Copy link
Contributor

For 3.11 and 3.12, I suggest that we revert a918589

Any objections?

cc. @pablogsal as 3.11 RM, and @Yhg1s as 3.12 RM.

facebook-github-bot pushed a commit to facebookincubator/cinder that referenced this issue Dec 22, 2023
…ted since 3.11)

Summary:
backport upstream PRs python/cpython#110163 and python/cpython#113233

upstream issues: python/cpython#89519 (Calling help executes classmethod property decorated methods) and python/cpython#113157 (Changed behavior of <instancemethod>.__get__ in Python 3.11)

upstream commits: [`7f9a99e8549b792662f2cd28bf38a4d4625bd402`](python/cpython@7f9a99e) and [`d058eaeed44766a8291013b275ad22f153935d3b`](python/cpython@d058eae)

Reviewed By: aleivag

Differential Revision: D52014322

fbshipit-source-id: 87de6d9587bd9cc49f053ca340adfc469b041f91
ryan-duve pushed a commit to ryan-duve/cpython that referenced this issue Dec 26, 2023
Restore behaviors before classmethod descriptor chaining was introduced.
kulikjak pushed a commit to kulikjak/cpython that referenced this issue Jan 22, 2024
Restore behaviors before classmethod descriptor chaining was introduced.
aisk pushed a commit to aisk/cpython that referenced this issue Feb 11, 2024
Restore behaviors before classmethod descriptor chaining was introduced.
rhettinger added a commit to rhettinger/cpython that referenced this issue Feb 14, 2024
woodruffw pushed a commit to woodruffw-forks/cpython that referenced this issue Mar 4, 2024
Glyphack pushed a commit to Glyphack/cpython that referenced this issue Sep 2, 2024
Restore behaviors before classmethod descriptor chaining was introduced.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type-bug An unexpected behavior, bug, or error
Projects
None yet
Development

No branches or pull requests

4 participants