]> granicus.if.org Git - python/commitdiff
PyClass_New(): put the extended Don Beaudry hook back in. When one of
authorGuido van Rossum <guido@python.org>
Fri, 7 Sep 2001 21:08:32 +0000 (21:08 +0000)
committerGuido van Rossum <guido@python.org>
Fri, 7 Sep 2001 21:08:32 +0000 (21:08 +0000)
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).

Objects/classobject.c

index a38f354b2a1e35ec8a1bb69fb2fc776790caf7e4..4b698425324663a179987c54d2154df3751d61dc 100644 (file)
@@ -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;