mirror of
https://github.com/python/cpython.git
synced 2025-07-24 03:35:53 +00:00
Merge issue 1294232 patch from 3.2
This commit is contained in:
commit
9715d26305
5 changed files with 244 additions and 23 deletions
|
@ -1915,6 +1915,42 @@ PyType_GetFlags(PyTypeObject *type)
|
|||
return type->tp_flags;
|
||||
}
|
||||
|
||||
/* Determine the most derived metatype. */
|
||||
PyTypeObject *
|
||||
_PyType_CalculateMetaclass(PyTypeObject *metatype, PyObject *bases)
|
||||
{
|
||||
Py_ssize_t i, nbases;
|
||||
PyTypeObject *winner;
|
||||
PyObject *tmp;
|
||||
PyTypeObject *tmptype;
|
||||
|
||||
/* Determine the proper metatype to deal with this,
|
||||
and check for metatype conflicts while we're at it.
|
||||
Note that if some other metatype wins to contract,
|
||||
it's possible that its instances are not types. */
|
||||
|
||||
nbases = PyTuple_GET_SIZE(bases);
|
||||
winner = metatype;
|
||||
for (i = 0; i < nbases; i++) {
|
||||
tmp = PyTuple_GET_ITEM(bases, i);
|
||||
tmptype = Py_TYPE(tmp);
|
||||
if (PyType_IsSubtype(winner, tmptype))
|
||||
continue;
|
||||
if (PyType_IsSubtype(tmptype, winner)) {
|
||||
winner = tmptype;
|
||||
continue;
|
||||
}
|
||||
/* else: */
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"metaclass conflict: "
|
||||
"the metaclass of a derived class "
|
||||
"must be a (non-strict) subclass "
|
||||
"of the metaclasses of all its bases");
|
||||
return NULL;
|
||||
}
|
||||
return winner;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
|
@ -1958,28 +1994,12 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds)
|
|||
&PyDict_Type, &dict))
|
||||
return NULL;
|
||||
|
||||
/* Determine the proper metatype to deal with this,
|
||||
and check for metatype conflicts while we're at it.
|
||||
Note that if some other metatype wins to contract,
|
||||
it's possible that its instances are not types. */
|
||||
nbases = PyTuple_GET_SIZE(bases);
|
||||
winner = metatype;
|
||||
for (i = 0; i < nbases; i++) {
|
||||
tmp = PyTuple_GET_ITEM(bases, i);
|
||||
tmptype = Py_TYPE(tmp);
|
||||
if (PyType_IsSubtype(winner, tmptype))
|
||||
continue;
|
||||
if (PyType_IsSubtype(tmptype, winner)) {
|
||||
winner = tmptype;
|
||||
continue;
|
||||
}
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"metaclass conflict: "
|
||||
"the metaclass of a derived class "
|
||||
"must be a (non-strict) subclass "
|
||||
"of the metaclasses of all its bases");
|
||||
/* Determine the proper metatype to deal with this: */
|
||||
winner = _PyType_CalculateMetaclass(metatype, bases);
|
||||
if (winner == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (winner != metatype) {
|
||||
if (winner->tp_new != type_new) /* Pass it to the winner */
|
||||
return winner->tp_new(winner, args, kwds);
|
||||
|
@ -1987,6 +2007,7 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds)
|
|||
}
|
||||
|
||||
/* Adjust for empty tuple bases */
|
||||
nbases = PyTuple_GET_SIZE(bases);
|
||||
if (nbases == 0) {
|
||||
bases = PyTuple_Pack(1, &PyBaseObject_Type);
|
||||
if (bases == NULL)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue