gh-106917: fix super classmethod calls to non-classmethods (#106977)
This commit is contained in:
parent
b383703491
commit
e5d5522612
@ -5,6 +5,9 @@ from unittest.mock import patch
|
|||||||
from test import shadowed_super
|
from test import shadowed_super
|
||||||
|
|
||||||
|
|
||||||
|
ADAPTIVE_WARMUP_DELAY = 2
|
||||||
|
|
||||||
|
|
||||||
class A:
|
class A:
|
||||||
def f(self):
|
def f(self):
|
||||||
return 'A'
|
return 'A'
|
||||||
@ -419,8 +422,47 @@ class TestSuper(unittest.TestCase):
|
|||||||
super(MyType, type(mytype)).__setattr__(mytype, "bar", 1)
|
super(MyType, type(mytype)).__setattr__(mytype, "bar", 1)
|
||||||
self.assertEqual(mytype.bar, 1)
|
self.assertEqual(mytype.bar, 1)
|
||||||
|
|
||||||
|
for _ in range(ADAPTIVE_WARMUP_DELAY):
|
||||||
test("foo1")
|
test("foo1")
|
||||||
test("foo2")
|
|
||||||
|
def test_reassigned_new(self):
|
||||||
|
class A:
|
||||||
|
def __new__(cls):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def __init_subclass__(cls):
|
||||||
|
if "__new__" not in cls.__dict__:
|
||||||
|
cls.__new__ = cls.__new__
|
||||||
|
|
||||||
|
class B(A):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class C(B):
|
||||||
|
def __new__(cls):
|
||||||
|
return super().__new__(cls)
|
||||||
|
|
||||||
|
for _ in range(ADAPTIVE_WARMUP_DELAY):
|
||||||
|
C()
|
||||||
|
|
||||||
|
def test_mixed_staticmethod_hierarchy(self):
|
||||||
|
# This test is just a desugared version of `test_reassigned_new`
|
||||||
|
class A:
|
||||||
|
@staticmethod
|
||||||
|
def some(cls, *args, **kwargs):
|
||||||
|
self.assertFalse(args)
|
||||||
|
self.assertFalse(kwargs)
|
||||||
|
|
||||||
|
class B(A):
|
||||||
|
def some(cls, *args, **kwargs):
|
||||||
|
return super().some(cls, *args, **kwargs)
|
||||||
|
|
||||||
|
class C(B):
|
||||||
|
@staticmethod
|
||||||
|
def some(cls):
|
||||||
|
return super().some(cls)
|
||||||
|
|
||||||
|
for _ in range(ADAPTIVE_WARMUP_DELAY):
|
||||||
|
C.some(C)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
@ -0,0 +1,4 @@
|
|||||||
|
Fix classmethod-style :func:`super` method calls (i.e., where the second
|
||||||
|
argument to :func:`super`, or the implied second argument drawn from
|
||||||
|
``self/cls`` in the case of zero-arg super, is a type) when the target of
|
||||||
|
the call is not a classmethod.
|
@ -1721,7 +1721,7 @@ dummy_func(
|
|||||||
PyTypeObject *cls = (PyTypeObject *)class;
|
PyTypeObject *cls = (PyTypeObject *)class;
|
||||||
int method_found = 0;
|
int method_found = 0;
|
||||||
res2 = _PySuper_Lookup(cls, self, name,
|
res2 = _PySuper_Lookup(cls, self, name,
|
||||||
cls->tp_getattro == PyObject_GenericGetAttr ? &method_found : NULL);
|
Py_TYPE(self)->tp_getattro == PyObject_GenericGetAttr ? &method_found : NULL);
|
||||||
Py_DECREF(global_super);
|
Py_DECREF(global_super);
|
||||||
Py_DECREF(class);
|
Py_DECREF(class);
|
||||||
if (res2 == NULL) {
|
if (res2 == NULL) {
|
||||||
|
2
Python/executor_cases.c.h
generated
2
Python/executor_cases.c.h
generated
@ -1406,7 +1406,7 @@
|
|||||||
PyTypeObject *cls = (PyTypeObject *)class;
|
PyTypeObject *cls = (PyTypeObject *)class;
|
||||||
int method_found = 0;
|
int method_found = 0;
|
||||||
res2 = _PySuper_Lookup(cls, self, name,
|
res2 = _PySuper_Lookup(cls, self, name,
|
||||||
cls->tp_getattro == PyObject_GenericGetAttr ? &method_found : NULL);
|
Py_TYPE(self)->tp_getattro == PyObject_GenericGetAttr ? &method_found : NULL);
|
||||||
Py_DECREF(global_super);
|
Py_DECREF(global_super);
|
||||||
Py_DECREF(class);
|
Py_DECREF(class);
|
||||||
if (res2 == NULL) {
|
if (res2 == NULL) {
|
||||||
|
2
Python/generated_cases.c.h
generated
2
Python/generated_cases.c.h
generated
@ -2154,7 +2154,7 @@
|
|||||||
PyTypeObject *cls = (PyTypeObject *)class;
|
PyTypeObject *cls = (PyTypeObject *)class;
|
||||||
int method_found = 0;
|
int method_found = 0;
|
||||||
res2 = _PySuper_Lookup(cls, self, name,
|
res2 = _PySuper_Lookup(cls, self, name,
|
||||||
cls->tp_getattro == PyObject_GenericGetAttr ? &method_found : NULL);
|
Py_TYPE(self)->tp_getattro == PyObject_GenericGetAttr ? &method_found : NULL);
|
||||||
Py_DECREF(global_super);
|
Py_DECREF(global_super);
|
||||||
Py_DECREF(class);
|
Py_DECREF(class);
|
||||||
if (res2 == NULL) {
|
if (res2 == NULL) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user