mirror of
https://github.com/python/cpython.git
synced 2025-08-28 04:35:02 +00:00
GH-114806. Don't specialize calls to classes with metaclasses. (GH-114870)
This commit is contained in:
parent
97cc58f977
commit
e66d0399cc
3 changed files with 24 additions and 0 deletions
|
@ -771,6 +771,22 @@ class ClassTests(unittest.TestCase):
|
||||||
with self.assertRaises(RecursionError):
|
with self.assertRaises(RecursionError):
|
||||||
add_one_level()
|
add_one_level()
|
||||||
|
|
||||||
|
def testMetaclassCallOptimization(self):
|
||||||
|
calls = 0
|
||||||
|
|
||||||
|
class TypeMetaclass(type):
|
||||||
|
def __call__(cls, *args, **kwargs):
|
||||||
|
nonlocal calls
|
||||||
|
calls += 1
|
||||||
|
return type.__call__(cls, *args, **kwargs)
|
||||||
|
|
||||||
|
class Type(metaclass=TypeMetaclass):
|
||||||
|
def __init__(self, obj):
|
||||||
|
self._obj = obj
|
||||||
|
|
||||||
|
for i in range(100):
|
||||||
|
Type(i)
|
||||||
|
self.assertEqual(calls, 100)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
No longer specialize calls to classes, if those classes have metaclasses.
|
||||||
|
Fixes bug where the ``__call__`` method of the metaclass was not being
|
||||||
|
called.
|
|
@ -540,6 +540,7 @@ _PyCode_Quicken(PyCodeObject *code)
|
||||||
#define SPEC_FAIL_CALL_METHOD_WRAPPER 28
|
#define SPEC_FAIL_CALL_METHOD_WRAPPER 28
|
||||||
#define SPEC_FAIL_CALL_OPERATOR_WRAPPER 29
|
#define SPEC_FAIL_CALL_OPERATOR_WRAPPER 29
|
||||||
#define SPEC_FAIL_CALL_INIT_NOT_SIMPLE 30
|
#define SPEC_FAIL_CALL_INIT_NOT_SIMPLE 30
|
||||||
|
#define SPEC_FAIL_CALL_METACLASS 31
|
||||||
|
|
||||||
/* COMPARE_OP */
|
/* COMPARE_OP */
|
||||||
#define SPEC_FAIL_COMPARE_OP_DIFFERENT_TYPES 12
|
#define SPEC_FAIL_COMPARE_OP_DIFFERENT_TYPES 12
|
||||||
|
@ -1757,6 +1758,10 @@ specialize_class_call(PyObject *callable, _Py_CODEUNIT *instr, int nargs)
|
||||||
SPEC_FAIL_CALL_STR : SPEC_FAIL_CALL_CLASS_NO_VECTORCALL);
|
SPEC_FAIL_CALL_STR : SPEC_FAIL_CALL_CLASS_NO_VECTORCALL);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
if (Py_TYPE(tp) != &PyType_Type) {
|
||||||
|
SPECIALIZATION_FAIL(CALL, SPEC_FAIL_CALL_METACLASS);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
if (tp->tp_new == PyBaseObject_Type.tp_new) {
|
if (tp->tp_new == PyBaseObject_Type.tp_new) {
|
||||||
PyFunctionObject *init = get_init_for_simple_managed_python_class(tp);
|
PyFunctionObject *init = get_init_for_simple_managed_python_class(tp);
|
||||||
if (type_get_version(tp, CALL) == 0) {
|
if (type_get_version(tp, CALL) == 0) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue