diff -r 758523f024d6 Modules/_randommodule.c --- a/Modules/_randommodule.c Wed Aug 15 15:31:47 2012 +0200 +++ b/Modules/_randommodule.c Wed Aug 15 16:06:18 2012 +0200 @@ -82,9 +82,38 @@ int index; } RandomObject; -static PyTypeObject Random_Type; +typedef struct { + PyObject *Random_Type; +} _randomstate; -#define RandomObject_Check(v) (Py_TYPE(v) == &Random_Type) + +#define _random_state(o) ((_randomstate *)PyModule_GetState(o)) + +static int +_random_clear(PyObject *m) +{ + Py_CLEAR(_random_state(m)->Random_Type); + return 0; +} + +static int +_random_traverse(PyObject *m, visitproc visit, void *arg) +{ + Py_VISIT(_random_state(m)->Random_Type); + return 0; +} + +static void +_random_free(void *m) +{ + _random_clear((PyObject *)m); +} + +static PyModuleDef _randommodule; + +#define _randomstate_global ((_randomstate *)PyModule_GetState(PyState_FindModule(&_randommodule))) + +#define RandomObject_Check(v) (Py_TYPE(v) == _randomstate_global->Random_Type) /* Random methods */ @@ -418,7 +447,8 @@ RandomObject *self; PyObject *tmp; - if (type == &Random_Type && !_PyArg_NoKeywords("Random()", kwds)) + if (type == (PyTypeObject *)_randomstate_global->Random_Type + && !_PyArg_NoKeywords("Random()", kwds)) return NULL; self = (RandomObject *)type->tp_alloc(type, 0); @@ -451,50 +481,25 @@ PyDoc_STRVAR(random_doc, "Random() -> create a random number generator with its own internal state."); -static PyTypeObject Random_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_random.Random", /*tp_name*/ - sizeof(RandomObject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - 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*/ - PyObject_GenericGetAttr, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ - random_doc, /*tp_doc*/ - 0, /*tp_traverse*/ - 0, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - random_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*/ - 0, /*tp_init*/ - 0, /*tp_alloc*/ - random_new, /*tp_new*/ - PyObject_Free, /*tp_free*/ - 0, /*tp_is_gc*/ +static PyType_Slot Random_Type_slots[] = { + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_doc, random_doc}, + {Py_tp_methods, random_methods}, + {Py_tp_new, random_new}, + {Py_tp_free, PyObject_Free}, + {Py_tp_bases, }, + {0, 0} }; +static PyType_Spec Random_Type_spec = { + "_random.Random", + sizeof(RandomObject), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + Random_Type_slots, +}; + + PyDoc_STRVAR(module_doc, "Module implements the Mersenne Twister random number generator."); @@ -503,12 +508,12 @@ PyModuleDef_HEAD_INIT, "_random", module_doc, - -1, + sizeof(_randomstate), NULL, NULL, - NULL, - NULL, - NULL + _random_traverse, + _random_clear, + _random_free }; PyMODINIT_FUNC @@ -516,12 +521,15 @@ { PyObject *m; - if (PyType_Ready(&Random_Type) < 0) - return NULL; m = PyModule_Create(&_randommodule); if (m == NULL) return NULL; - Py_INCREF(&Random_Type); - PyModule_AddObject(m, "Random", (PyObject *)&Random_Type); + + _random_state(m)->Random_Type = PyType_FromSpec(&Random_Type_spec); + if (_random_state(m)->Random_Type == NULL) + return NULL; + + Py_INCREF(_random_state(m)->Random_Type); + PyModule_AddObject(m, "Random", _random_state(m)->Random_Type); return m; }