diff -r c3ed80250df0 Modules/md5module.c --- a/Modules/md5module.c Thu Aug 16 10:48:57 2012 +0200 +++ b/Modules/md5module.c Thu Aug 16 10:55:25 2012 +0200 @@ -48,6 +48,37 @@ struct md5_state hash_state; } MD5object; +typedef struct { + PyObject *MD5type; +} _md5state; + + +#define _md5_state(o) ((_md5state *)PyModule_GetState(o)) + +static int +_md5_clear(PyObject *m) +{ + Py_CLEAR(_md5_state(m)->MD5type); + return 0; +} + +static int +_md5_traverse(PyObject *m, visitproc visit, void *arg) +{ + Py_VISIT(_md5_state(m)->MD5type); + return 0; +} + +static void +_md5_free(void *m) +{ + _md5_clear((PyObject *)m); +} + +static PyModuleDef _md5module; + +#define _md5state_global ((_md5state *)PyModule_GetState(PyState_FindModule(&_md5module))) + /* ------------------------------------------------------------------------ * @@ -315,13 +346,11 @@ * ------------------------------------------------------------------------ */ -static PyTypeObject MD5type; - - static MD5object * newMD5object(void) { - return (MD5object *)PyObject_New(MD5object, &MD5type); + Py_INCREF(_md5state_global->MD5type); + return (MD5object *)PyObject_New(MD5object, (PyTypeObject *)_md5state_global->MD5type); } @@ -330,7 +359,11 @@ static void MD5_dealloc(PyObject *ptr) { + PyTypeObject *type = Py_TYPE(ptr); PyObject_Del(ptr); + if((void *)type->tp_dealloc == (void *)MD5_dealloc) { + Py_DECREF(type); + } } @@ -343,7 +376,7 @@ { MD5object *newobj; - if (Py_TYPE(self) == &MD5type) { + if (Py_TYPE(self) == (PyTypeObject *)_md5state_global->MD5type) { if ( (newobj = newMD5object())==NULL) return NULL; } else { @@ -467,38 +500,20 @@ {NULL} /* Sentinel */ }; -static PyTypeObject MD5type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_md5.md5", /*tp_name*/ - sizeof(MD5object), /*tp_size*/ - 0, /*tp_itemsize*/ - /* methods */ - MD5_dealloc, /*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, /*tp_flags*/ - 0, /*tp_doc*/ - 0, /*tp_traverse*/ - 0, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - MD5_methods, /* tp_methods */ - NULL, /* tp_members */ - MD5_getseters, /* tp_getset */ +static PyType_Slot MD5type_slots[] = { + {Py_tp_dealloc, MD5_dealloc}, + {Py_tp_methods, MD5_methods}, + {Py_tp_members, NULL}, + {Py_tp_getset, MD5_getseters}, + {0, 0} +}; + +static PyType_Spec MD5type_spec = { + "_md5.md5", + sizeof(MD5object), + 0, + Py_TPFLAGS_DEFAULT, + MD5type_slots, }; @@ -563,19 +578,26 @@ PyModuleDef_HEAD_INIT, "_md5", NULL, - -1, + sizeof(_md5state), MD5_functions, NULL, - NULL, - NULL, - NULL + _md5_traverse, + _md5_clear, + _md5_free }; PyMODINIT_FUNC PyInit__md5(void) { - Py_TYPE(&MD5type) = &PyType_Type; - if (PyType_Ready(&MD5type) < 0) + PyObject *m; + + m = PyModule_Create(&_md5module); + if(!m) return NULL; - return PyModule_Create(&_md5module); + + _md5_state(m)->MD5type = PyType_FromSpec(&MD5type_spec); + if(_md5_state(m)->MD5type == NULL) + return NULL; + + return m; }