mirror of
https://github.com/python/cpython.git
synced 2025-08-04 17:08:35 +00:00
Issue #23722: Initialize __class__ from type.__new__()
The __class__ cell used by zero-argument super() is now initialized from type.__new__ rather than __build_class__, so class methods relying on that will now work correctly when called from metaclass methods during class creation. Patch by Martin Teichmann.
This commit is contained in:
parent
fc3f7d5677
commit
944368e1cc
8 changed files with 1358 additions and 1258 deletions
|
@ -2285,7 +2285,7 @@ static PyObject *
|
|||
type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
PyObject *name, *bases = NULL, *orig_dict, *dict = NULL;
|
||||
PyObject *qualname, *slots = NULL, *tmp, *newslots;
|
||||
PyObject *qualname, *slots = NULL, *tmp, *newslots, *cell;
|
||||
PyTypeObject *type = NULL, *base, *tmptype, *winner;
|
||||
PyHeapTypeObject *et;
|
||||
PyMemberDef *mp;
|
||||
|
@ -2293,6 +2293,7 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds)
|
|||
int j, may_add_dict, may_add_weak, add_dict, add_weak;
|
||||
_Py_IDENTIFIER(__qualname__);
|
||||
_Py_IDENTIFIER(__slots__);
|
||||
_Py_IDENTIFIER(__classcell__);
|
||||
|
||||
assert(args != NULL && PyTuple_Check(args));
|
||||
assert(kwds == NULL || PyDict_Check(kwds));
|
||||
|
@ -2559,7 +2560,7 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds)
|
|||
}
|
||||
et->ht_qualname = qualname ? qualname : et->ht_name;
|
||||
Py_INCREF(et->ht_qualname);
|
||||
if (qualname != NULL && PyDict_DelItem(dict, PyId___qualname__.object) < 0)
|
||||
if (qualname != NULL && _PyDict_DelItemId(dict, &PyId___qualname__) < 0)
|
||||
goto error;
|
||||
|
||||
/* Set tp_doc to a copy of dict['__doc__'], if the latter is there
|
||||
|
@ -2685,6 +2686,14 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds)
|
|||
else
|
||||
type->tp_free = PyObject_Del;
|
||||
|
||||
/* store type in class' cell */
|
||||
cell = _PyDict_GetItemId(dict, &PyId___classcell__);
|
||||
if (cell != NULL && PyCell_Check(cell)) {
|
||||
PyCell_Set(cell, (PyObject *) type);
|
||||
_PyDict_DelItemId(dict, &PyId___classcell__);
|
||||
PyErr_Clear();
|
||||
}
|
||||
|
||||
/* Initialize the rest */
|
||||
if (PyType_Ready(type) < 0)
|
||||
goto error;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue