New submission from Michael J. Sullivan <[email protected]>:
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)
----------
components: Interpreter Core
messages: 413310
nosy: msullivan
priority: normal
severity: normal
status: open
title: Wrapping a bound method with a @classmethod no longer works
versions: Python 3.10, Python 3.11, Python 3.9
_______________________________________
Python tracker <[email protected]>
<https://bugs.python.org/issue46764>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com