Skip to content

Commit 5fff491

Browse files
[3.12] gh-105035: fix super() calls on unusual types (e.g. meta-types) (GH-105094) (#105117)
gh-105035: fix super() calls on unusual types (e.g. meta-types) (GH-105094) (cherry picked from commit 68c75c3) Co-authored-by: Carl Meyer <carl@oddbird.net>
1 parent 9ae49e3 commit 5fff491

File tree

4 files changed

+239
-221
lines changed

4 files changed

+239
-221
lines changed

Lib/test/test_super.py

+12
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,18 @@ def method(self):
410410

411411
self.assertEqual(C().method(), mysuper)
412412

413+
def test_unusual_getattro(self):
414+
class MyType(type):
415+
pass
416+
417+
def test(name):
418+
mytype = MyType(name, (MyType,), {})
419+
super(MyType, type(mytype)).__setattr__(mytype, "bar", 1)
420+
self.assertEqual(mytype.bar, 1)
421+
422+
test("foo1")
423+
test("foo2")
424+
413425

414426
if __name__ == "__main__":
415427
unittest.main()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix :func:`super` calls on types with custom :attr:`tp_getattro`
2+
implementation (e.g. meta-types.)

Python/bytecodes.c

+3-1
Original file line numberDiff line numberDiff line change
@@ -1660,8 +1660,10 @@ dummy_func(
16601660
DEOPT_IF(!PyType_Check(class), LOAD_SUPER_ATTR);
16611661
STAT_INC(LOAD_SUPER_ATTR, hit);
16621662
PyObject *name = GETITEM(frame->f_code->co_names, oparg >> 2);
1663+
PyTypeObject *cls = (PyTypeObject *)class;
16631664
int method_found = 0;
1664-
res2 = _PySuper_Lookup((PyTypeObject *)class, self, name, &method_found);
1665+
res2 = _PySuper_Lookup(cls, self, name,
1666+
cls->tp_getattro == PyObject_GenericGetAttr ? &method_found : NULL);
16651667
Py_DECREF(global_super);
16661668
Py_DECREF(class);
16671669
if (res2 == NULL) {

0 commit comments

Comments
 (0)