diff options
author | Guido van Rossum <guido@python.org> | 2001-09-07 21:08:32 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 2001-09-07 21:08:32 (GMT) |
commit | 28d80b1058c73b296f41861ac9f39534c7a3ee4b (patch) | |
tree | 111413a04d155d54f5da724ce369a5d0cf655609 /Objects/classobject.c | |
parent | 8700b4281af0561d9aafd3cc14c44d79c2a0934b (diff) | |
download | cpython-28d80b1058c73b296f41861ac9f39534c7a3ee4b.zip cpython-28d80b1058c73b296f41861ac9f39534c7a3ee4b.tar.gz cpython-28d80b1058c73b296f41861ac9f39534c7a3ee4b.tar.bz2 |
PyClass_New(): put the extended Don Beaudry hook back in. When one of
the base classes is not a classic class, and its class (the metaclass)
is callable, call the metaclass to do the deed.
One effect of this is that, when mixing classic and new-style classes
amongst the bases of a class, it doesn't matter whether the first base
class is a classic class or not: you will always get the error
"TypeError: metatype conflict among bases". (Formerly, with a classic
class first, you'd get "TypeError: PyClass_New: base must be a class".)
Another effect is that multiple inheritance from ExtensionClass.Base,
with a classic class as the first class, transfers control to the
ExtensionClass.Base class. This is what we need for SF #443239 (and
also for running Zope under 2.2a4, before ExtensionClass is replaced).
Diffstat (limited to 'Objects/classobject.c')
-rw-r--r-- | Objects/classobject.c | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/Objects/classobject.c b/Objects/classobject.c index a38f354..4b69842 100644 --- a/Objects/classobject.c +++ b/Objects/classobject.c @@ -65,15 +65,25 @@ PyClass_New(PyObject *bases, PyObject *dict, PyObject *name) return NULL; } else { - int i; + int i, n; + PyObject *base; if (!PyTuple_Check(bases)) { PyErr_SetString(PyExc_TypeError, "PyClass_New: bases must be a tuple"); return NULL; } - i = PyTuple_Size(bases); - while (--i >= 0) { - if (!PyClass_Check(PyTuple_GetItem(bases, i))) { + n = PyTuple_Size(bases); + for (i = 0; i < n; i++) { + base = PyTuple_GET_ITEM(bases, i); + if (!PyClass_Check(base)) { + if (PyCallable_Check( + (PyObject *) base->ob_type)) + return PyObject_CallFunction( + (PyObject *) base->ob_type, + "OOO", + name, + bases, + dict); PyErr_SetString(PyExc_TypeError, "PyClass_New: base must be a class"); return NULL; |