gh-106917: fix super classmethod calls to non-classmethods (#106977)

This commit is contained in:
Carl Meyer 2023-07-24 14:14:56 -06:00 committed by GitHub
parent b383703491
commit e5d5522612
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 51 additions and 5 deletions

View file

@ -5,6 +5,9 @@
from test import shadowed_super
ADAPTIVE_WARMUP_DELAY = 2
class A:
def f(self):
return 'A'
@ -419,8 +422,47 @@ def test(name):
super(MyType, type(mytype)).__setattr__(mytype, "bar", 1)
self.assertEqual(mytype.bar, 1)
test("foo1")
test("foo2")
for _ in range(ADAPTIVE_WARMUP_DELAY):
test("foo1")
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__":

View file

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

View file

@ -1721,7 +1721,7 @@ dummy_func(
PyTypeObject *cls = (PyTypeObject *)class;
int method_found = 0;
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(class);
if (res2 == NULL) {

View file

@ -1406,7 +1406,7 @@
PyTypeObject *cls = (PyTypeObject *)class;
int method_found = 0;
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(class);
if (res2 == NULL) {

View file

@ -2154,7 +2154,7 @@
PyTypeObject *cls = (PyTypeObject *)class;
int method_found = 0;
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(class);
if (res2 == NULL) {