Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
[3.12] gh-106917: fix super classmethod calls to non-classmethods (GH…
…-106977).

(cherry picked from commit e5d5522)

Co-authored-by: Carl Meyer <carl@oddbird.net>
  • Loading branch information
carljm committed Jul 24, 2023
commit 4e1f4a52a5f7d279e33282a3ae0d16a2d01a523a
46 changes: 44 additions & 2 deletions Lib/test/test_super.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
from test import shadowed_super


ADAPTIVE_WARMUP_DELAY = 2


class A:
def f(self):
return 'A'
Expand Down Expand Up @@ -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__":
Expand Down
Original file line number Diff line number Diff line change
@@ -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.
2 changes: 1 addition & 1 deletion Python/bytecodes.c
Original file line number Diff line number Diff line change
Expand Up @@ -1663,7 +1663,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) {
Expand Down
2 changes: 1 addition & 1 deletion Python/generated_cases.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.