Skip to content

Wrapping a bound method with a @classmethod no longer works #90920

Closed

Description

@msullivan
mannequin
BPO 46764
Nosy @rhettinger, @msullivan
PRs
  • bpo-46764: Fix wrapping bound method with @classmethod #31367
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = 'https://github.com/rhettinger'
    closed_at = None
    created_at = <Date 2022-02-16.01:56:29.217>
    labels = ['interpreter-core', 'type-bug', '3.9', '3.10', '3.11']
    title = 'Wrapping a bound method with a @classmethod no longer works'
    updated_at = <Date 2022-02-17.20:02:42.052>
    user = 'https://github.com/msullivan'

    bugs.python.org fields:

    activity = <Date 2022-02-17.20:02:42.052>
    actor = 'rhettinger'
    assignee = 'rhettinger'
    closed = False
    closed_date = None
    closer = None
    components = ['Interpreter Core']
    creation = <Date 2022-02-16.01:56:29.217>
    creator = 'msullivan'
    dependencies = []
    files = []
    hgrepos = []
    issue_num = 46764
    keywords = ['patch']
    message_count = 2.0
    messages = ['413310', '413450']
    nosy_count = 2.0
    nosy_names = ['rhettinger', 'msullivan']
    pr_nums = ['31367']
    priority = 'normal'
    resolution = None
    stage = 'patch review'
    status = 'open'
    superseder = None
    type = 'behavior'
    url = 'https://bugs.python.org/issue46764'
    versions = ['Python 3.9', 'Python 3.10', 'Python 3.11']

    Activity

    1. msullivan commented on Feb 16, 2022

      msullivanmannequin
      MannequinAuthor
      class A:
          def foo(self, cls): return 1
      
      class B: pass
      
      class B:
          bar = classmethod(A().foo)
      
      B.bar()

      In Python 3.8 and prior, this worked. Since Python 3.9, it produces "TypeError: A.foo() missing 1 required positional argument: 'cls'"

      I tracked it down, and the issue was introduced by https://github.com/python/cpython/pull/8405/files, which makes classmethod's tp_descr_get invoke its argument tp_descr_get when present instead of calling PyMethod_New. That this was a semantics change that could break existing code may have been missed (though it is a fairly obscure such change).

      The reason it breaks this case in particular of bound methods, though, is that bound methods have a tp_descr_get that does nothing (increfs the method and then returns it). Dropping that tp_descr_get fixes this issue and doesn't introduce any test failures. Not sure if there is some potential downstream breakage of that?

      (This issue was originally reported to me by Jared Hance)

    2. rhettinger commented on Feb 17, 2022

      @rhettinger
      Contributor

      This seems like a reasonable fix. I'll wait a bit so that others can comment as well.

      FWIW, we looking a potentially reverting the whole line of development starting with that commit. It has caused a number of problems and no longer looks tenable. See https://bugs.python.org/issue45356

    3. self-assigned this
      on Feb 17, 2022
    4. transferred this issue fromon Apr 10, 2022
    5. iritkatriel commented on Oct 7, 2022

      @iritkatriel
      Member

      The PR was merged, and I think it resolves this issue.

    6. iritkatriel commented on Oct 7, 2022

      @iritkatriel
      Member

      Unless it can still be backported.

    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

    Metadata

    Metadata

    Assignees

    Labels

    3.10 (EOL)end of life3.11only security fixes3.9 (EOL)end of lifeinterpreter-core(Objects, Python, Grammar, and Parser dirs)type-bugAn unexpected behavior, bug, or error

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions