bpo-1635741: Port _random to multiphase initialization (GH-23359)
Signed-off-by: Christian Heimes <christian@python.org>
This commit is contained in:
parent
13b865f0e1
commit
cc0cd43c0f
|
@ -0,0 +1 @@
|
||||||
|
Port _random extension module to multiphase initialization (:pep:`489`)
|
|
@ -93,7 +93,8 @@ get_random_state(PyObject *module)
|
||||||
|
|
||||||
static struct PyModuleDef _randommodule;
|
static struct PyModuleDef _randommodule;
|
||||||
|
|
||||||
#define _randomstate_global get_random_state(PyState_FindModule(&_randommodule))
|
#define _randomstate_type(type) \
|
||||||
|
(get_random_state(_PyType_GetModuleByDef(type, &_randommodule)))
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
PyObject_HEAD
|
PyObject_HEAD
|
||||||
|
@ -106,9 +107,9 @@ typedef struct {
|
||||||
|
|
||||||
/*[clinic input]
|
/*[clinic input]
|
||||||
module _random
|
module _random
|
||||||
class _random.Random "RandomObject *" "&Random_Type"
|
class _random.Random "RandomObject *" "_randomstate_type(type)->Random_Type"
|
||||||
[clinic start generated code]*/
|
[clinic start generated code]*/
|
||||||
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=f79898ae7847c321]*/
|
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=70a2c99619474983]*/
|
||||||
|
|
||||||
/* Random methods */
|
/* Random methods */
|
||||||
|
|
||||||
|
@ -290,7 +291,8 @@ random_seed(RandomObject *self, PyObject *arg)
|
||||||
} else if (PyLong_Check(arg)) {
|
} else if (PyLong_Check(arg)) {
|
||||||
/* Calling int.__abs__() prevents calling arg.__abs__(), which might
|
/* Calling int.__abs__() prevents calling arg.__abs__(), which might
|
||||||
return an invalid value. See issue #31478. */
|
return an invalid value. See issue #31478. */
|
||||||
n = PyObject_CallOneArg(_randomstate_global->Long___abs__, arg);
|
_randomstate *state = _randomstate_type(Py_TYPE(self));
|
||||||
|
n = PyObject_CallOneArg(state->Long___abs__, arg);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Py_hash_t hash = PyObject_Hash(arg);
|
Py_hash_t hash = PyObject_Hash(arg);
|
||||||
|
@ -517,8 +519,9 @@ random_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||||
{
|
{
|
||||||
RandomObject *self;
|
RandomObject *self;
|
||||||
PyObject *tmp;
|
PyObject *tmp;
|
||||||
|
_randomstate *state = _randomstate_type(type);
|
||||||
|
|
||||||
if (type == (PyTypeObject*)_randomstate_global->Random_Type &&
|
if (type == (PyTypeObject*)state->Random_Type &&
|
||||||
!_PyArg_NoKeywords("Random()", kwds)) {
|
!_PyArg_NoKeywords("Random()", kwds)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -567,6 +570,45 @@ static PyType_Spec Random_Type_spec = {
|
||||||
PyDoc_STRVAR(module_doc,
|
PyDoc_STRVAR(module_doc,
|
||||||
"Module implements the Mersenne Twister random number generator.");
|
"Module implements the Mersenne Twister random number generator.");
|
||||||
|
|
||||||
|
static int
|
||||||
|
_random_exec(PyObject *module)
|
||||||
|
{
|
||||||
|
_randomstate *state = get_random_state(module);
|
||||||
|
|
||||||
|
state->Random_Type = PyType_FromModuleAndSpec(
|
||||||
|
module, &Random_Type_spec, NULL);
|
||||||
|
if (state->Random_Type == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (PyModule_AddType(module, (PyTypeObject *)state->Random_Type) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Look up and save int.__abs__, which is needed in random_seed(). */
|
||||||
|
PyObject *longval = longval = PyLong_FromLong(0);
|
||||||
|
if (longval == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject *longtype = PyObject_Type(longval);
|
||||||
|
Py_DECREF(longval);
|
||||||
|
if (longtype == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
state->Long___abs__ = PyObject_GetAttrString(longtype, "__abs__");
|
||||||
|
Py_DECREF(longtype);
|
||||||
|
if (state->Long___abs__ == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyModuleDef_Slot _random_slots[] = {
|
||||||
|
{Py_mod_exec, _random_exec},
|
||||||
|
{0, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
_random_traverse(PyObject *module, visitproc visit, void *arg)
|
_random_traverse(PyObject *module, visitproc visit, void *arg)
|
||||||
{
|
{
|
||||||
|
@ -594,7 +636,7 @@ static struct PyModuleDef _randommodule = {
|
||||||
module_doc,
|
module_doc,
|
||||||
sizeof(_randomstate),
|
sizeof(_randomstate),
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
_random_slots,
|
||||||
_random_traverse,
|
_random_traverse,
|
||||||
_random_clear,
|
_random_clear,
|
||||||
_random_free,
|
_random_free,
|
||||||
|
@ -603,43 +645,5 @@ static struct PyModuleDef _randommodule = {
|
||||||
PyMODINIT_FUNC
|
PyMODINIT_FUNC
|
||||||
PyInit__random(void)
|
PyInit__random(void)
|
||||||
{
|
{
|
||||||
PyObject *m;
|
return PyModuleDef_Init(&_randommodule);
|
||||||
|
|
||||||
PyObject *Random_Type = PyType_FromSpec(&Random_Type_spec);
|
|
||||||
if (Random_Type == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
m = PyModule_Create(&_randommodule);
|
|
||||||
if (m == NULL) {
|
|
||||||
Py_DECREF(Random_Type);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
get_random_state(m)->Random_Type = Random_Type;
|
|
||||||
|
|
||||||
Py_INCREF(Random_Type);
|
|
||||||
PyModule_AddObject(m, "Random", Random_Type);
|
|
||||||
|
|
||||||
/* Look up and save int.__abs__, which is needed in random_seed(). */
|
|
||||||
PyObject *longval = NULL, *longtype = NULL;
|
|
||||||
longval = PyLong_FromLong(0);
|
|
||||||
if (longval == NULL) goto fail;
|
|
||||||
|
|
||||||
longtype = PyObject_Type(longval);
|
|
||||||
if (longtype == NULL) goto fail;
|
|
||||||
|
|
||||||
PyObject *abs = PyObject_GetAttrString(longtype, "__abs__");
|
|
||||||
if (abs == NULL) goto fail;
|
|
||||||
|
|
||||||
Py_DECREF(longtype);
|
|
||||||
Py_DECREF(longval);
|
|
||||||
get_random_state(m)->Long___abs__ = abs;
|
|
||||||
|
|
||||||
return m;
|
|
||||||
|
|
||||||
fail:
|
|
||||||
Py_XDECREF(longtype);
|
|
||||||
Py_XDECREF(longval);
|
|
||||||
Py_DECREF(m);
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue