diff options
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/Setup.dist | 2 | ||||
-rw-r--r-- | Modules/cPickle.c | 4 | ||||
-rw-r--r-- | Modules/config.c.in | 2 | ||||
-rw-r--r-- | Modules/xxsubtype.c | 233 |
4 files changed, 240 insertions, 1 deletions
diff --git a/Modules/Setup.dist b/Modules/Setup.dist index 9114414..e9c2a94 100644 --- a/Modules/Setup.dist +++ b/Modules/Setup.dist @@ -464,3 +464,5 @@ GLHACK=-Dclear=__GLclear # Example -- included for reference only: # xx xxmodule.c +# Another example -- the 'xxsubtype' module shows C-level subtyping in action +xxsubtype xxsubtype.c diff --git a/Modules/cPickle.c b/Modules/cPickle.c index e3cc58d..b27339f 100644 --- a/Modules/cPickle.c +++ b/Modules/cPickle.c @@ -1869,6 +1869,10 @@ save(Picklerobject *self, PyObject *args, int pers_save) { res = save_tuple(self, args); goto finally; } + if (type == &PyType_Type) { + res = save_global(self, args, NULL); + goto finally; + } break; case 'l': diff --git a/Modules/config.c.in b/Modules/config.c.in index 5a5878f..0d5e8b0 100644 --- a/Modules/config.c.in +++ b/Modules/config.c.in @@ -37,7 +37,7 @@ struct _inittab _PyImport_Inittab[] = { {"__main__", NULL}, {"__builtin__", NULL}, {"sys", NULL}, - {"exceptions", init_exceptions}, + {"exceptions", NULL}, /* Sentinel */ {0, 0} diff --git a/Modules/xxsubtype.c b/Modules/xxsubtype.c new file mode 100644 index 0000000..60d8c7d --- /dev/null +++ b/Modules/xxsubtype.c @@ -0,0 +1,233 @@ +#include "Python.h" + +/* Examples showing how to subtype the builtin list and dict types from C. */ + +/* spamlist -- a list subtype */ + +typedef struct { + PyListObject list; + int state; +} spamlistobject; + +static PyObject * +spamlist_getstate(spamlistobject *self, PyObject *args) +{ + if (!PyArg_ParseTuple(args, ":getstate")) + return NULL; + return PyInt_FromLong(self->state); +} + +static PyObject * +spamlist_setstate(spamlistobject *self, PyObject *args) +{ + int state; + + if (!PyArg_ParseTuple(args, "i:setstate", &state)) + return NULL; + self->state = state; + Py_INCREF(Py_None); + return Py_None; +} + +static PyMethodDef spamlist_methods[] = { + {"getstate", (PyCFunction)spamlist_getstate, METH_VARARGS, + "getstate() -> state"}, + {"setstate", (PyCFunction)spamlist_setstate, METH_VARARGS, + "setstate(state)"}, + {NULL, NULL}, +}; + +staticforward PyTypeObject spamlist_type; + +static int +spamlist_init(spamlistobject *self, PyObject *args, PyObject *kwds) +{ + if (PyList_Type.tp_init((PyObject *)self, args, kwds) < 0) + return -1; + self->state = 0; + return 0; +} + +static PyTypeObject spamlist_type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, + "spamlist", + sizeof(spamlistobject), + 0, + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + spamlist_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &PyList_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)spamlist_init, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +/* spamdict -- a dict subtype */ + +typedef struct { + PyDictObject dict; + int state; +} spamdictobject; + +static PyObject * +spamdict_getstate(spamdictobject *self, PyObject *args) +{ + if (!PyArg_ParseTuple(args, ":getstate")) + return NULL; + return PyInt_FromLong(self->state); +} + +static PyObject * +spamdict_setstate(spamdictobject *self, PyObject *args) +{ + int state; + + if (!PyArg_ParseTuple(args, "i:setstate", &state)) + return NULL; + self->state = state; + Py_INCREF(Py_None); + return Py_None; +} + +static PyMethodDef spamdict_methods[] = { + {"getstate", (PyCFunction)spamdict_getstate, METH_VARARGS, + "getstate() -> state"}, + {"setstate", (PyCFunction)spamdict_setstate, METH_VARARGS, + "setstate(state)"}, + {NULL, NULL}, +}; + +staticforward PyTypeObject spamdict_type; + +static int +spamdict_init(spamdictobject *self, PyObject *args, PyObject *kwds) +{ + if (PyDict_Type.tp_init((PyObject *)self, args, kwds) < 0) + return -1; + self->state = 0; + return 0; +} + +static PyTypeObject spamdict_type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, + "spamdict", + sizeof(spamdictobject), + 0, + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + spamdict_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &PyDict_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)spamdict_init, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +PyObject * +spam_bench(PyObject *self, PyObject *args) +{ + PyObject *obj, *name, *res; + int n = 1000; + time_t t0, t1; + + if (!PyArg_ParseTuple(args, "OS|i", &obj, &name, &n)) + return NULL; + t0 = clock(); + while (--n >= 0) { + res = PyObject_GetAttr(obj, name); + if (res == NULL) + return NULL; + Py_DECREF(res); + } + t1 = clock(); + return PyFloat_FromDouble((double)(t1-t0) / CLOCKS_PER_SEC); +} + +static PyMethodDef xxsubtype_functions[] = { + {"bench", spam_bench, METH_VARARGS}, + {NULL, NULL} /* sentinel */ +}; + +DL_EXPORT(void) +initxxsubtype(void) +{ + PyObject *m, *d; + + m = Py_InitModule("xxsubtype", xxsubtype_functions); + if (m == NULL) + return; + + if (PyType_InitDict(&spamlist_type) < 0) + return; + if (PyType_InitDict(&spamdict_type) < 0) + return; + + d = PyModule_GetDict(m); + if (d == NULL) + return; + + Py_INCREF(&spamlist_type); + if (PyDict_SetItemString(d, "spamlist", + (PyObject *) &spamlist_type) < 0) + return; + + Py_INCREF(&spamdict_type); + if (PyDict_SetItemString(d, "spamdict", + (PyObject *) &spamdict_type) < 0) + return; +} |