summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2001-09-07 21:08:32 (GMT)
committerGuido van Rossum <guido@python.org>2001-09-07 21:08:32 (GMT)
commit28d80b1058c73b296f41861ac9f39534c7a3ee4b (patch)
tree111413a04d155d54f5da724ce369a5d0cf655609 /Objects
parent8700b4281af0561d9aafd3cc14c44d79c2a0934b (diff)
downloadcpython-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')
-rw-r--r--Objects/classobject.c18
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;