Skip to content

Commit c638629

Browse files
Carl Meyerfacebook-github-bot
authored andcommitted
fix super() calls on unusual types (e.g. meta-types)
Summary: This bug was discovered in the upstream `LOAD_SUPER_ATTR` implementation in 3.12b1, and it also exists in the Cinder implementation. `_PyObject_GetMethod` checks whether the type has a non-standard `tp_getattro` (i.e. not `PyObject_GenericGetAttr`), and if so, refuses to attempt the load-method optimization. We didn't have this check in the `super()` optimization, causing incompatible behavior in the case of a `super()` lookup on a type with unusual `tp_getattro`, e.g. meta-types. Upstream fix is python/cpython#105094 Reviewed By: mpage Differential Revision: D46281340 fbshipit-source-id: 41aba762d3e2925042a3d897a690317ba2767cf2
1 parent 11a85b3 commit c638629

2 files changed

Lines changed: 12 additions & 0 deletions

File tree

Lib/test/test_super.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,15 @@ def test_super_init_leaks(self):
317317
for i in range(1000):
318318
super.__init__(sp, int, i)
319319

320+
def test_unusual_getattro(self):
321+
class MyType(type):
322+
pass
323+
324+
mytype = MyType("foo", (MyType,), {})
325+
super(MyType, type(mytype)).__setattr__(mytype, "bar", 1)
326+
327+
self.assertEqual(mytype.bar, 1)
328+
320329

321330
if __name__ == "__main__":
322331
unittest.main()

Python/ceval.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1724,6 +1724,9 @@ Ci_SuperLookupMethodOrAttr(PyThreadState *tstate,
17241724
}
17251725
return result;
17261726
}
1727+
if (type->tp_getattro != PyObject_GenericGetAttr) {
1728+
meth_found = NULL;
1729+
}
17271730
return Ci_Super_Lookup(type, self, name, NULL, meth_found);
17281731
}
17291732

0 commit comments

Comments
 (0)