Kaydet (Commit) 7851eea5 authored tarafından Guido van Rossum's avatar Guido van Rossum

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?).
üst 2400fa4a
...@@ -3500,25 +3500,32 @@ import_all_from(PyObject *locals, PyObject *v) ...@@ -3500,25 +3500,32 @@ import_all_from(PyObject *locals, PyObject *v)
static PyObject * static PyObject *
build_class(PyObject *methods, PyObject *bases, PyObject *name) build_class(PyObject *methods, PyObject *bases, PyObject *name)
{ {
PyObject *metaclass = NULL; PyObject *metaclass = NULL, *result, *base;
if (PyDict_Check(methods)) if (PyDict_Check(methods))
metaclass = PyDict_GetItemString(methods, "__metaclass__"); metaclass = PyDict_GetItemString(methods, "__metaclass__");
if (metaclass != NULL)
if (metaclass == NULL) { Py_INCREF(methods);
if (PyTuple_Check(bases) && PyTuple_GET_SIZE(bases) > 0) else if (PyTuple_Check(bases) && PyTuple_GET_SIZE(bases) > 0) {
metaclass = (PyObject *) base = PyTuple_GET_ITEM(bases, 0);
PyTuple_GET_ITEM(bases, 0)->ob_type; metaclass = PyObject_GetAttrString(base, "__class__");
else { if (metaclass == NULL) {
PyObject *g = PyEval_GetGlobals(); PyErr_Clear();
if (g != NULL && PyDict_Check(g)) metaclass = (PyObject *)base->ob_type;
metaclass = PyDict_GetItemString( Py_INCREF(metaclass);
g, "__metaclass__");
if (metaclass == NULL)
metaclass = (PyObject *) &PyClass_Type;
} }
} }
return PyObject_CallFunction(metaclass, "OOO", name, bases, methods); 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;
} }
static int static int
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment