gh-105035: fix super() calls on unusual types (e.g. meta-types) (#105094)

This commit is contained in:
Carl Meyer 2023-05-30 14:36:24 -06:00 committed by GitHub
parent 49f90ba1ea
commit 68c75c3153
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 240 additions and 222 deletions

View File

@ -410,6 +410,18 @@ class TestSuper(unittest.TestCase):
self.assertEqual(C().method(), mysuper)
def test_unusual_getattro(self):
class MyType(type):
pass
def test(name):
mytype = MyType(name, (MyType,), {})
super(MyType, type(mytype)).__setattr__(mytype, "bar", 1)
self.assertEqual(mytype.bar, 1)
test("foo1")
test("foo2")
if __name__ == "__main__":
unittest.main()

View File

@ -0,0 +1,2 @@
Fix :func:`super` calls on types with custom :attr:`tp_getattro`
implementation (e.g. meta-types.)

View File

@ -1660,8 +1660,10 @@ dummy_func(
DEOPT_IF(!PyType_Check(class), LOAD_SUPER_ATTR);
STAT_INC(LOAD_SUPER_ATTR, hit);
PyObject *name = GETITEM(frame->f_code->co_names, oparg >> 2);
PyTypeObject *cls = (PyTypeObject *)class;
int method_found = 0;
res2 = _PySuper_Lookup((PyTypeObject *)class, self, name, &method_found);
res2 = _PySuper_Lookup(cls, self, name,
cls->tp_getattro == PyObject_GenericGetAttr ? &method_found : NULL);
Py_DECREF(global_super);
Py_DECREF(class);
if (res2 == NULL) {

File diff suppressed because it is too large Load Diff