7979#define UPPER_MASK 0x80000000U /* most significant w-r bits */
8080#define LOWER_MASK 0x7fffffffU /* least significant r bits */
8181
82+ typedef struct {
83+ PyObject * Random_Type ;
84+ PyObject * Long___abs__ ;
85+ } _randomstate ;
86+
87+ #define _randomstate (o ) ((_randomstate *)PyModule_GetState(o))
88+
89+ static struct PyModuleDef _randommodule ;
90+
91+ #define _randomstate_global _randomstate(PyState_FindModule(&_randommodule))
92+
8293typedef struct {
8394 PyObject_HEAD
8495 int index ;
8596 uint32_t state [N ];
8697} RandomObject ;
8798
88- static PyTypeObject Random_Type ;
89-
90- #define RandomObject_Check (v ) (Py_TYPE(v) == &Random_Type)
9199
92100#include "clinic/_randommodule.c.h"
93101
@@ -256,6 +264,7 @@ random_seed(RandomObject *self, PyObject *arg)
256264 uint32_t * key = NULL ;
257265 size_t bits , keyused ;
258266 int res ;
267+ PyObject * args [1 ];
259268
260269 if (arg == NULL || arg == Py_None ) {
261270 if (random_seed_urandom (self ) < 0 ) {
@@ -272,10 +281,14 @@ random_seed(RandomObject *self, PyObject *arg)
272281 * So: if the arg is a PyLong, use its absolute value.
273282 * Otherwise use its hash value, cast to unsigned.
274283 */
275- if (PyLong_Check (arg )) {
284+ if (PyLong_CheckExact (arg )) {
285+ n = PyNumber_Absolute (arg );
286+ } else if (PyLong_Check (arg )) {
276287 /* Calling int.__abs__() prevents calling arg.__abs__(), which might
277288 return an invalid value. See issue #31478. */
278- n = PyLong_Type .tp_as_number -> nb_absolute (arg );
289+ args [0 ] = arg ;
290+ n = _PyObject_Vectorcall (_randomstate_global -> Long___abs__ , args , 0 ,
291+ NULL );
279292 }
280293 else {
281294 Py_hash_t hash = PyObject_Hash (arg );
@@ -500,10 +513,12 @@ random_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
500513 RandomObject * self ;
501514 PyObject * tmp ;
502515
503- if (type == & Random_Type && !_PyArg_NoKeywords ("Random" , kwds ))
516+ if (type == (PyTypeObject * )_randomstate_global -> Random_Type &&
517+ !_PyArg_NoKeywords ("Random()" , kwds )) {
504518 return NULL ;
519+ }
505520
506- self = (RandomObject * )type -> tp_alloc (type , 0 );
521+ self = (RandomObject * )PyType_GenericAlloc (type , 0 );
507522 if (self == NULL )
508523 return NULL ;
509524 tmp = random_seed (self , args );
@@ -527,77 +542,97 @@ static PyMethodDef random_methods[] = {
527542PyDoc_STRVAR (random_doc ,
528543"Random() -> create a random number generator with its own internal state." );
529544
530- static PyTypeObject Random_Type = {
531- PyVarObject_HEAD_INIT (NULL , 0 )
532- "_random.Random" , /*tp_name*/
533- sizeof (RandomObject ), /*tp_basicsize*/
534- 0 , /*tp_itemsize*/
535- /* methods */
536- 0 , /*tp_dealloc*/
537- 0 , /*tp_vectorcall_offset*/
538- 0 , /*tp_getattr*/
539- 0 , /*tp_setattr*/
540- 0 , /*tp_as_async*/
541- 0 , /*tp_repr*/
542- 0 , /*tp_as_number*/
543- 0 , /*tp_as_sequence*/
544- 0 , /*tp_as_mapping*/
545- 0 , /*tp_hash*/
546- 0 , /*tp_call*/
547- 0 , /*tp_str*/
548- PyObject_GenericGetAttr , /*tp_getattro*/
549- 0 , /*tp_setattro*/
550- 0 , /*tp_as_buffer*/
551- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE , /*tp_flags*/
552- random_doc , /*tp_doc*/
553- 0 , /*tp_traverse*/
554- 0 , /*tp_clear*/
555- 0 , /*tp_richcompare*/
556- 0 , /*tp_weaklistoffset*/
557- 0 , /*tp_iter*/
558- 0 , /*tp_iternext*/
559- random_methods , /*tp_methods*/
560- 0 , /*tp_members*/
561- 0 , /*tp_getset*/
562- 0 , /*tp_base*/
563- 0 , /*tp_dict*/
564- 0 , /*tp_descr_get*/
565- 0 , /*tp_descr_set*/
566- 0 , /*tp_dictoffset*/
567- 0 , /*tp_init*/
568- 0 , /*tp_alloc*/
569- random_new , /*tp_new*/
570- PyObject_Free , /*tp_free*/
571- 0 , /*tp_is_gc*/
545+ static PyType_Slot Random_Type_slots [] = {
546+ {Py_tp_doc , random_doc },
547+ {Py_tp_methods , random_methods },
548+ {Py_tp_new , random_new },
549+ {Py_tp_free , PyObject_Free },
550+ {0 , 0 },
551+ };
552+
553+ static PyType_Spec Random_Type_spec = {
554+ "_random.Random" ,
555+ sizeof (RandomObject ),
556+ 0 ,
557+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE ,
558+ Random_Type_slots
572559};
573560
574561PyDoc_STRVAR (module_doc ,
575562"Module implements the Mersenne Twister random number generator." );
576563
564+ static int
565+ _random_traverse (PyObject * module , visitproc visit , void * arg )
566+ {
567+ Py_VISIT (_randomstate (module )-> Random_Type );
568+ return 0 ;
569+ }
570+
571+ static int
572+ _random_clear (PyObject * module )
573+ {
574+ Py_CLEAR (_randomstate (module )-> Random_Type );
575+ return 0 ;
576+ }
577+
578+ static void
579+ _random_free (void * module )
580+ {
581+ _random_clear ((PyObject * )module );
582+ }
577583
578584static struct PyModuleDef _randommodule = {
579585 PyModuleDef_HEAD_INIT ,
580586 "_random" ,
581587 module_doc ,
582- -1 ,
583- NULL ,
588+ sizeof (_randomstate ),
584589 NULL ,
585590 NULL ,
586- NULL ,
587- NULL
591+ _random_traverse ,
592+ _random_clear ,
593+ _random_free ,
588594};
589595
590596PyMODINIT_FUNC
591597PyInit__random (void )
592598{
593599 PyObject * m ;
594600
595- if (PyType_Ready (& Random_Type ) < 0 )
601+ PyObject * Random_Type = PyType_FromSpec (& Random_Type_spec );
602+ if (Random_Type == NULL ) {
596603 return NULL ;
604+ }
605+
597606 m = PyModule_Create (& _randommodule );
598- if (m == NULL )
607+ if (m == NULL ) {
608+ Py_DECREF (Random_Type );
599609 return NULL ;
600- Py_INCREF (& Random_Type );
601- PyModule_AddObject (m , "Random" , (PyObject * )& Random_Type );
610+ }
611+ _randomstate (m )-> Random_Type = Random_Type ;
612+
613+ Py_INCREF (Random_Type );
614+ PyModule_AddObject (m , "Random" , Random_Type );
615+
616+ /* Look up and save int.__abs__, which is needed in random_seed(). */
617+ PyObject * longval = NULL , * longtype = NULL ;
618+ longval = PyLong_FromLong (0 );
619+ if (longval == NULL ) goto fail ;
620+
621+ longtype = PyObject_Type (longval );
622+ if (longtype == NULL ) goto fail ;
623+
624+ PyObject * abs = PyObject_GetAttrString (longtype , "__abs__" );
625+ if (abs == NULL ) goto fail ;
626+
627+ Py_DECREF (longtype );
628+ Py_DECREF (longval );
629+ _randomstate (m )-> Long___abs__ = abs ;
630+
602631 return m ;
632+
633+ fail :
634+ Py_XDECREF (longtype );
635+ Py_XDECREF (longval );
636+ Py_DECREF (m );
637+ return NULL ;
603638}
0 commit comments