diff -r 3058f1710751 Modules/xxsubtype.c --- a/Modules/xxsubtype.c Sun Sep 02 13:06:10 2012 +0200 +++ b/Modules/xxsubtype.c Sun Sep 02 16:28:21 2012 +0200 @@ -16,6 +16,41 @@ */ #define DEFERRED_ADDRESS(ADDR) 0 +typedef struct { + PyObject *spamlist_type; + PyObject *spamdict_type; +} xxsubtypestate; + + +#define xxsubtype_state(o) ((xxsubtypestate *)PyModule_GetState(o)) + +static int +xxsubtype_clear(PyObject *m) +{ + Py_CLEAR(xxsubtype_state(m)->spamlist_type); + Py_CLEAR(xxsubtype_state(m)->spamdict_type); + return 0; +} + +static int +xxsubtype_traverse(PyObject *m, visitproc visit, void *arg) +{ + Py_VISIT(xxsubtype_state(m)->spamlist_type); + Py_VISIT(xxsubtype_state(m)->spamdict_type); + return 0; +} + +static void +xxsubtype_free(void *m) +{ + xxsubtype_clear((PyObject *)m); +} + +static PyModuleDef xxsubtypemodule; + +#define xxsubtype_state_global \ + ((xxsubtypestate *)PyModule_GetState(PyState_FindModule(&xxsubtypemodule))) + /* spamlist -- a list subtype */ typedef struct { @@ -100,47 +135,23 @@ {0} }; -static PyTypeObject spamlist_type = { - PyVarObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type), 0) +static PyType_Slot spamlist_type_slots[] = { + {Py_tp_base, NULL}, + {Py_tp_methods, spamlist_methods}, + {Py_tp_getset, spamlist_getsets}, + {Py_tp_init, (initproc)spamlist_init}, + {0, 0} +}; + +static PyType_Spec spamlist_type_spec = { "xxsubtype.spamlist", sizeof(spamlistobject), 0, - 0, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - 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 */ - spamlist_getsets, /* tp_getset */ - DEFERRED_ADDRESS(&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 */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + spamlist_type_slots, }; + /* spamdict -- a dict subtype */ typedef struct { @@ -191,47 +202,23 @@ {0} }; -static PyTypeObject spamdict_type = { - PyVarObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type), 0) +static PyType_Slot spamdict_type_slots[] = { + {Py_tp_base, NULL}, + {Py_tp_methods, spamdict_methods}, + {Py_tp_members, spamdict_members}, + {Py_tp_init, (initproc)spamdict_init}, + {0, 0} +}; + +static PyType_Spec spamdict_type_spec = { "xxsubtype.spamdict", sizeof(spamdictobject), 0, - 0, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - 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 */ - spamdict_members, /* tp_members */ - 0, /* tp_getset */ - DEFERRED_ADDRESS(&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 */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + spamdict_type_slots, }; + static PyObject * spam_bench(PyObject *self, PyObject *args) { @@ -261,12 +248,12 @@ PyModuleDef_HEAD_INIT, "xxsubtype", xxsubtype__doc__, - -1, - xxsubtype_functions, + sizeof(xxsubtypestate), + xxsubtype_functions, NULL, - NULL, - NULL, - NULL + xxsubtype_traverse, + xxsubtype_clear, + xxsubtype_free }; @@ -275,35 +262,33 @@ { PyObject *m; + m = PyModule_Create(&xxsubtypemodule); + if (m == NULL) + return NULL; + /* Fill in deferred data addresses. This must be done before PyType_Ready() is called. Note that PyType_Ready() automatically initializes the ob.ob_type field to &PyType_Type if it's NULL, so it's not necessary to fill in ob_type first. */ - spamdict_type.tp_base = &PyDict_Type; - if (PyType_Ready(&spamdict_type) < 0) + + spamdict_type_slots[0].pfunc = &PyDict_Type; + xxsubtype_state(m)->spamdict_type = PyType_FromSpec(&spamdict_type_spec); + if (xxsubtype_state(m)->spamdict_type == NULL) return NULL; - spamlist_type.tp_base = &PyList_Type; - if (PyType_Ready(&spamlist_type) < 0) + spamlist_type_slots[0].pfunc = &PyList_Type; + xxsubtype_state(m)->spamlist_type = PyType_FromSpec(&spamlist_type_spec); + if (xxsubtype_state(m)->spamlist_type == NULL) return NULL; - m = PyModule_Create(&xxsubtypemodule); - if (m == NULL) + Py_INCREF(xxsubtype_state(m)->spamlist_type); + if (PyModule_AddObject(m, "spamlist", + xxsubtype_state(m)->spamlist_type) < 0) return NULL; - if (PyType_Ready(&spamlist_type) < 0) - return NULL; - if (PyType_Ready(&spamdict_type) < 0) - return NULL; - - Py_INCREF(&spamlist_type); - if (PyModule_AddObject(m, "spamlist", - (PyObject *) &spamlist_type) < 0) - return NULL; - - Py_INCREF(&spamdict_type); + Py_INCREF(xxsubtype_state(m)->spamdict_type); if (PyModule_AddObject(m, "spamdict", - (PyObject *) &spamdict_type) < 0) + xxsubtype_state(m)->spamdict_type) < 0) return NULL; return m; }