[Python-checkins] CVS: python/dist/src/Python ceval.c,2.273,2.274
Guido van Rossum
gvanrossum@users.sourceforge.net
Wed, 12 Sep 2001 12:19:20 -0700
Update of /cvsroot/python/python/dist/src/Python
In directory usw-pr-cvs1:/tmp/cvs-serv28674
Modified Files:
ceval.c
Log Message:
build_class(): one more (hopefully the last) step on the way to
backwards compatibility. When using the class of the first base as
the metaclass, use its __class__ attribute in preference over its
ob_type slot. This ensures that we can still use classic classes as
metaclasse, as shown in the original "Metaclasses" essay. This also
makes all the examples in Demo/metaclasses/ work again (maybe these
should be turned into a test suite?).
Index: ceval.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v
retrieving revision 2.273
retrieving revision 2.274
diff -C2 -d -r2.273 -r2.274
*** ceval.c 2001/09/04 19:03:35 2.273
--- ceval.c 2001/09/12 19:19:18 2.274
***************
*** 3501,3523 ****
build_class(PyObject *methods, PyObject *bases, PyObject *name)
{
! PyObject *metaclass = NULL;
if (PyDict_Check(methods))
metaclass = PyDict_GetItemString(methods, "__metaclass__");
!
! if (metaclass == NULL) {
! if (PyTuple_Check(bases) && PyTuple_GET_SIZE(bases) > 0)
! metaclass = (PyObject *)
! PyTuple_GET_ITEM(bases, 0)->ob_type;
! else {
! PyObject *g = PyEval_GetGlobals();
! if (g != NULL && PyDict_Check(g))
! metaclass = PyDict_GetItemString(
! g, "__metaclass__");
! if (metaclass == NULL)
! metaclass = (PyObject *) &PyClass_Type;
}
}
! return PyObject_CallFunction(metaclass, "OOO", name, bases, methods);
}
--- 3501,3530 ----
build_class(PyObject *methods, PyObject *bases, PyObject *name)
{
! PyObject *metaclass = NULL, *result, *base;
if (PyDict_Check(methods))
metaclass = PyDict_GetItemString(methods, "__metaclass__");
! if (metaclass != NULL)
! Py_INCREF(methods);
! else if (PyTuple_Check(bases) && PyTuple_GET_SIZE(bases) > 0) {
! base = PyTuple_GET_ITEM(bases, 0);
! metaclass = PyObject_GetAttrString(base, "__class__");
! if (metaclass == NULL) {
! PyErr_Clear();
! metaclass = (PyObject *)base->ob_type;
! Py_INCREF(metaclass);
}
}
! else {
! PyObject *g = PyEval_GetGlobals();
! if (g != NULL && PyDict_Check(g))
! metaclass = PyDict_GetItemString(g, "__metaclass__");
! if (metaclass == NULL)
! metaclass = (PyObject *) &PyClass_Type;
! Py_INCREF(metaclass);
! }
! result = PyObject_CallFunction(metaclass, "OOO", name, bases, methods);
! Py_DECREF(metaclass);
! return result;
}