Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 55b9ab5

Browse files
committed
Extend the "Don Beaudry hack" with "Guido's corollary" -- if the base
class has a __class__ attribute, call that to create the new class. This allows us to write metaclasses purely in C!
1 parent fd16ca4 commit 55b9ab5

1 file changed

Lines changed: 27 additions & 10 deletions

File tree

Python/ceval.c

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2689,22 +2689,39 @@ build_class(methods, bases, name)
26892689
return NULL;
26902690
}
26912691
for (i = PyTuple_Size(bases); --i >= 0; ) {
2692+
/* XXX Is it intentional that the *last* base gets a
2693+
chance at this first? */
26922694
PyObject *base = PyTuple_GET_ITEM(bases, i);
26932695
if (!PyClass_Check(base)) {
26942696
/* Call the base's *type*, if it is callable.
26952697
This code is a hook for Donald Beaudry's
26962698
and Jim Fulton's type extensions. In
26972699
unexended Python it will never be triggered
2698-
since its types are not callable. */
2699-
if (base->ob_type->ob_type->tp_call) {
2700-
PyObject *args;
2701-
PyObject *class;
2702-
args = Py_BuildValue("(OOO)",
2703-
name, bases, methods);
2704-
class = PyEval_CallObject(
2705-
(PyObject *)base->ob_type, args);
2706-
Py_DECREF(args);
2707-
return class;
2700+
since its types are not callable.
2701+
Ditto: call the bases's *class*, if it has
2702+
one. This makes the same thing possible
2703+
without writing C code. A true meta-object
2704+
protocol! */
2705+
PyObject *basetype = (PyObject *)base->ob_type;
2706+
PyObject *callable = NULL;
2707+
if (PyCallable_Check(basetype))
2708+
callable = basetype;
2709+
else
2710+
callable = PyObject_GetAttrString(
2711+
base, "__class__");
2712+
if (callable) {
2713+
PyObject *args;
2714+
PyObject *newclass = NULL;
2715+
args = Py_BuildValue(
2716+
"(OOO)", name, bases, methods);
2717+
if (args != NULL) {
2718+
newclass = PyEval_CallObject(
2719+
callable, args);
2720+
Py_DECREF(args);
2721+
}
2722+
if (callable != basetype)
2723+
Py_DECREF(callable);
2724+
return newclass;
27082725
}
27092726
PyErr_SetString(PyExc_TypeError,
27102727
"base is not a class object");

0 commit comments

Comments
 (0)