diff -r e90e6d53fbb3 Modules/_bz2module.c --- a/Modules/_bz2module.c Tue Aug 14 20:37:18 2012 +0200 +++ b/Modules/_bz2module.c Tue Aug 14 20:47:15 2012 +0200 @@ -58,6 +58,39 @@ #endif } BZ2Decompressor; +typedef struct { + PyObject *BZ2Compressor_Type; + PyObject *BZ2Decompressor_Type; +} _bz2state; + +#define _bz2state(o) ((_bz2state *)PyModule_GetState(o)) + +static int +_bz2_clear(PyObject *m) +{ + Py_CLEAR(_bz2state(m)->BZ2Compressor_Type); + Py_CLEAR(_bz2state(m)->BZ2Decompressor_Type); + return 0; +} + +static int +_bz2_traverse(PyObject *m, visitproc visit, void *arg) +{ + Py_VISIT(_bz2state(m)->BZ2Compressor_Type); + Py_VISIT(_bz2state(m)->BZ2Decompressor_Type); + return 0; +} + +static void +_bz2_free(void *m) +{ + _bz2_clear((PyObject *)m); +} + +static struct PyModuleDef _bz2module; + +#define _bz2state_global ((_bz2state*) \ + PyModule_GetState(PyState_FindModule(&_bz2module))) /* Helper functions. */ @@ -276,12 +309,14 @@ static void BZ2Compressor_dealloc(BZ2Compressor *self) { + PyTypeObject *type = Py_TYPE(self); BZ2_bzCompressEnd(&self->bzs); #ifdef WITH_THREAD if (self->lock != NULL) PyThread_free_lock(self->lock); #endif - Py_TYPE(self)->tp_free((PyObject *)self); + type->tp_free((PyObject *)self); + Py_DECREF(type); } static PyMethodDef BZ2Compressor_methods[] = { @@ -301,46 +336,23 @@ "\n" "For one-shot compression, use the compress() function instead.\n"); -static PyTypeObject BZ2Compressor_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_bz2.BZ2Compressor", /* tp_name */ - sizeof(BZ2Compressor), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)BZ2Compressor_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 */ - BZ2Compressor__doc__, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - BZ2Compressor_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)BZ2Compressor_init, /* tp_init */ - 0, /* tp_alloc */ - PyType_GenericNew, /* tp_new */ +static PyType_Slot BZ2Compressor_Type_slots[] = { + {Py_tp_dealloc, (destructor)BZ2Compressor_dealloc}, + {Py_tp_methods, BZ2Compressor_methods}, + {Py_tp_init, (initproc)BZ2Compressor_init}, + {Py_tp_new, PyType_GenericNew}, + {Py_tp_doc, BZ2Compressor__doc__}, + {Py_tp_free, }, + {0, 0} }; +static PyType_Spec BZ2Compressor_Type_spec = { + "_bz2.BZ2Compressor", + sizeof(BZ2Compressor), + 0, + Py_TPFLAGS_DEFAULT, + BZ2Compressor_Type_slots, +}; + /* BZ2Decompressor class. */ @@ -473,13 +485,15 @@ static void BZ2Decompressor_dealloc(BZ2Decompressor *self) { + PyTypeObject *type = Py_TYPE(self); BZ2_bzDecompressEnd(&self->bzs); Py_CLEAR(self->unused_data); #ifdef WITH_THREAD if (self->lock != NULL) PyThread_free_lock(self->lock); #endif - Py_TYPE(self)->tp_free((PyObject *)self); + type->tp_free((PyObject *)self); + Py_DECREF(type); } static PyMethodDef BZ2Decompressor_methods[] = { @@ -509,47 +523,26 @@ "\n" "For one-shot decompression, use the decompress() function instead.\n"); -static PyTypeObject BZ2Decompressor_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_bz2.BZ2Decompressor", /* tp_name */ - sizeof(BZ2Decompressor), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)BZ2Decompressor_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 */ - BZ2Decompressor__doc__, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - BZ2Decompressor_methods, /* tp_methods */ - BZ2Decompressor_members, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)BZ2Decompressor_init, /* tp_init */ - 0, /* tp_alloc */ - PyType_GenericNew, /* tp_new */ +static PyType_Slot BZ2Decompressor_Type_slots[] = { + {Py_tp_dealloc, (destructor)BZ2Decompressor_dealloc}, + {Py_tp_methods, BZ2Decompressor_methods}, + {Py_tp_members, BZ2Decompressor_members}, + {Py_tp_init, (initproc)BZ2Decompressor_init}, + {Py_tp_new, PyType_GenericNew}, + {Py_tp_doc, BZ2Decompressor__doc__}, + {Py_tp_free, }, + {0, 0} }; +static PyType_Spec BZ2Decompressor_Type_spec = { + "_bz2.BZ2Decompressor", + sizeof(BZ2Decompressor), + 0, + Py_TPFLAGS_DEFAULT, + BZ2Decompressor_Type_slots, +}; + + /* Module initialization. */ @@ -557,12 +550,12 @@ PyModuleDef_HEAD_INIT, "_bz2", NULL, - -1, + sizeof(_bz2state), NULL, NULL, - NULL, - NULL, - NULL + _bz2_traverse, + _bz2_clear, + _bz2_free }; PyMODINIT_FUNC @@ -570,21 +563,33 @@ { PyObject *m; - if (PyType_Ready(&BZ2Compressor_Type) < 0) - return NULL; - if (PyType_Ready(&BZ2Decompressor_Type) < 0) + m = PyState_FindModule(&_bz2module); + if(!m){ + m = PyModule_Create(&_bz2module); + if(m == NULL) + return NULL; + } else { + Py_INCREF(m); + return m; + } + + _bz2state(m)->BZ2Compressor_Type = + PyType_FromSpec(&BZ2Compressor_Type_spec); + if (_bz2state(m)->BZ2Compressor_Type == NULL) return NULL; - m = PyModule_Create(&_bz2module); - if (m == NULL) + _bz2state(m)->BZ2Decompressor_Type = + PyType_FromSpec(&BZ2Decompressor_Type_spec); + if (_bz2state(m)->BZ2Decompressor_Type == NULL) return NULL; - Py_INCREF(&BZ2Compressor_Type); - PyModule_AddObject(m, "BZ2Compressor", (PyObject *)&BZ2Compressor_Type); + Py_INCREF(_bz2state(m)->BZ2Compressor_Type); + PyModule_AddObject(m, "BZ2Compressor", + _bz2state(m)->BZ2Compressor_Type); - Py_INCREF(&BZ2Decompressor_Type); + Py_INCREF(_bz2state(m)->BZ2Decompressor_Type); PyModule_AddObject(m, "BZ2Decompressor", - (PyObject *)&BZ2Decompressor_Type); + _bz2state(m)->BZ2Decompressor_Type); return m; }