summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorNick Coghlan <ncoghlan@gmail.com>2016-09-11 04:45:49 (GMT)
committerNick Coghlan <ncoghlan@gmail.com>2016-09-11 04:45:49 (GMT)
commit944368e1cc90a0bebaaf1a0a6f4346a81d8f46ad (patch)
treeea2c59fec386dfbe32c0f53ba8a85f75860e554d /Objects
parentfc3f7d56773b3816eb0e8f4151239a0983aedb2c (diff)
downloadcpython-944368e1cc90a0bebaaf1a0a6f4346a81d8f46ad.zip
cpython-944368e1cc90a0bebaaf1a0a6f4346a81d8f46ad.tar.gz
cpython-944368e1cc90a0bebaaf1a0a6f4346a81d8f46ad.tar.bz2
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.
Diffstat (limited to 'Objects')
-rw-r--r--Objects/typeobject.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index 2675a48..5028304 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -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;