--- a/Modules/operator.c Fri Apr 20 14:37:17 2012 +0200 +++ b/Modules/operator.c Fri Apr 20 19:46:38 2012 +0200 @@ -155,6 +155,54 @@ return result; } +static PyObject* +build_class(PyObject *s, PyObject *args, PyObject *kw) +{ + static char *kwlist[] = {"name", "bases", "kwds", "exec_body", 0}; + PyObject *name; + PyObject *bases = NULL; + PyObject *kwds = NULL; + PyObject *exec_body = NULL; + PyObject *cls; + + if (!PyArg_ParseTupleAndKeywords(args, kw, "U|O!O!O:build_class", kwlist, + &name, + &PyTuple_Type, &bases, + &PyDict_Type, &kwds, + &exec_body)) { + return NULL; + } + + if (exec_body != NULL) { + if (exec_body == Py_None) { + exec_body = NULL; + } + else if (!PyCallable_Check(exec_body)) { + PyErr_SetString(PyExc_TypeError, "build_class: exec_body is not a callable"); + return NULL; + } + } + + if (bases == NULL) { + bases = PyTuple_New(0); + if (bases == NULL) { + return NULL; + } + } + else { + Py_INCREF(bases); + } + + cls = _PyType_BuildClass(exec_body, name, bases, kwds); + Py_DECREF(bases); + return cls; +} + +PyDoc_STRVAR(build_class_doc, + "build_class(name, bases=(), kwds={}, exec_body=None) -> cls\n\ + \n\ + Dynamically create a class object."); + #undef spam1 #undef spam2 #undef spam1o @@ -227,6 +275,8 @@ spam2(gt,__gt__, "gt(a, b) -- Same as a>b.") spam2(ge,__ge__, "ge(a, b) -- Same as a>=b.") +{"build_class", (PyCFunction)build_class, METH_VARARGS | METH_KEYWORDS, build_class_doc}, + {NULL, NULL} /* sentinel */ };