[Python-checkins] bpo-1635741: Port _random to multiphase initialization (GH-23359)

miss-islington webhook-mailer at python.org
Thu Nov 19 02:46:34 EST 2020


https://github.com/python/cpython/commit/cc0cd43c0f96dac413e54855e9c77ec4b73bd2f8
commit: cc0cd43c0f96dac413e54855e9c77ec4b73bd2f8
branch: master
author: Christian Heimes <christian at python.org>
committer: miss-islington <31488909+miss-islington at users.noreply.github.com>
date: 2020-11-18T23:46:29-08:00
summary:

bpo-1635741: Port _random to multiphase initialization (GH-23359)



Signed-off-by: Christian Heimes <christian at python.org>

files:
A Misc/NEWS.d/next/C API/2020-11-18-09-16-23.bpo-1635741.gkoI7Y.rst
M Modules/_randommodule.c

diff --git a/Misc/NEWS.d/next/C API/2020-11-18-09-16-23.bpo-1635741.gkoI7Y.rst b/Misc/NEWS.d/next/C API/2020-11-18-09-16-23.bpo-1635741.gkoI7Y.rst
new file mode 100644
index 0000000000000..1f300dca55485
--- /dev/null
+++ b/Misc/NEWS.d/next/C API/2020-11-18-09-16-23.bpo-1635741.gkoI7Y.rst	
@@ -0,0 +1 @@
+Port _random extension module to multiphase initialization (:pep:`489`)
diff --git a/Modules/_randommodule.c b/Modules/_randommodule.c
index d33870808622f..ad4fd474428d4 100644
--- a/Modules/_randommodule.c
+++ b/Modules/_randommodule.c
@@ -93,7 +93,8 @@ get_random_state(PyObject *module)
 
 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 {
     PyObject_HEAD
@@ -106,9 +107,9 @@ typedef struct {
 
 /*[clinic input]
 module _random
-class _random.Random "RandomObject *" "&Random_Type"
+class _random.Random "RandomObject *" "_randomstate_type(type)->Random_Type"
 [clinic start generated code]*/
-/*[clinic end generated code: output=da39a3ee5e6b4b0d input=f79898ae7847c321]*/
+/*[clinic end generated code: output=da39a3ee5e6b4b0d input=70a2c99619474983]*/
 
 /* Random methods */
 
@@ -290,7 +291,8 @@ random_seed(RandomObject *self, PyObject *arg)
     } else if (PyLong_Check(arg)) {
         /* Calling int.__abs__() prevents calling arg.__abs__(), which might
            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 {
         Py_hash_t hash = PyObject_Hash(arg);
@@ -517,8 +519,9 @@ random_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 {
     RandomObject *self;
     PyObject *tmp;
+    _randomstate *state = _randomstate_type(type);
 
-    if (type == (PyTypeObject*)_randomstate_global->Random_Type &&
+    if (type == (PyTypeObject*)state->Random_Type &&
         !_PyArg_NoKeywords("Random()", kwds)) {
         return NULL;
     }
@@ -567,6 +570,45 @@ static PyType_Spec Random_Type_spec = {
 PyDoc_STRVAR(module_doc,
 "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
 _random_traverse(PyObject *module, visitproc visit, void *arg)
 {
@@ -594,7 +636,7 @@ static struct PyModuleDef _randommodule = {
     module_doc,
     sizeof(_randomstate),
     NULL,
-    NULL,
+    _random_slots,
     _random_traverse,
     _random_clear,
     _random_free,
@@ -603,43 +645,5 @@ static struct PyModuleDef _randommodule = {
 PyMODINIT_FUNC
 PyInit__random(void)
 {
-    PyObject *m;
-
-    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;
+    return PyModuleDef_Init(&_randommodule);
 }



More information about the Python-checkins mailing list