Branch data Line data Source code
1 : : /* Random objects */
2 : :
3 : : /* ------------------------------------------------------------------
4 : : The code in this module was based on a download from:
5 : : http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html
6 : :
7 : : It was modified in 2002 by Raymond Hettinger as follows:
8 : :
9 : : * the principal computational lines untouched.
10 : :
11 : : * renamed genrand_res53() to random_random() and wrapped
12 : : in python calling/return code.
13 : :
14 : : * genrand_uint32() and the helper functions, init_genrand()
15 : : and init_by_array(), were declared static, wrapped in
16 : : Python calling/return code. also, their global data
17 : : references were replaced with structure references.
18 : :
19 : : * unused functions from the original were deleted.
20 : : new, original C python code was added to implement the
21 : : Random() interface.
22 : :
23 : : The following are the verbatim comments from the original code:
24 : :
25 : : A C-program for MT19937, with initialization improved 2002/1/26.
26 : : Coded by Takuji Nishimura and Makoto Matsumoto.
27 : :
28 : : Before using, initialize the state by using init_genrand(seed)
29 : : or init_by_array(init_key, key_length).
30 : :
31 : : Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
32 : : All rights reserved.
33 : :
34 : : Redistribution and use in source and binary forms, with or without
35 : : modification, are permitted provided that the following conditions
36 : : are met:
37 : :
38 : : 1. Redistributions of source code must retain the above copyright
39 : : notice, this list of conditions and the following disclaimer.
40 : :
41 : : 2. Redistributions in binary form must reproduce the above copyright
42 : : notice, this list of conditions and the following disclaimer in the
43 : : documentation and/or other materials provided with the distribution.
44 : :
45 : : 3. The names of its contributors may not be used to endorse or promote
46 : : products derived from this software without specific prior written
47 : : permission.
48 : :
49 : : THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
50 : : "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
51 : : LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
52 : : A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
53 : : CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
54 : : EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
55 : : PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
56 : : PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
57 : : LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
58 : : NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
59 : : SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
60 : :
61 : :
62 : : Any feedback is very welcome.
63 : : http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
64 : : email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
65 : : */
66 : :
67 : : /* ---------------------------------------------------------------*/
68 : :
69 : : #ifndef Py_BUILD_CORE_BUILTIN
70 : : # define Py_BUILD_CORE_MODULE 1
71 : : #endif
72 : :
73 : : #include "Python.h"
74 : : #include "pycore_moduleobject.h" // _PyModule_GetState()
75 : : #ifdef HAVE_PROCESS_H
76 : : # include <process.h> // getpid()
77 : : #endif
78 : :
79 : : /* Period parameters -- These are all magic. Don't change. */
80 : : #define N 624
81 : : #define M 397
82 : : #define MATRIX_A 0x9908b0dfU /* constant vector a */
83 : : #define UPPER_MASK 0x80000000U /* most significant w-r bits */
84 : : #define LOWER_MASK 0x7fffffffU /* least significant r bits */
85 : :
86 : : typedef struct {
87 : : PyObject *Random_Type;
88 : : PyObject *Long___abs__;
89 : : } _randomstate;
90 : :
91 : : static inline _randomstate*
92 : 89142 : get_random_state(PyObject *module)
93 : : {
94 : 89142 : void *state = _PyModule_GetState(module);
95 : : assert(state != NULL);
96 : 89142 : return (_randomstate *)state;
97 : : }
98 : :
99 : : static struct PyModuleDef _randommodule;
100 : :
101 : : #define _randomstate_type(type) \
102 : : (get_random_state(PyType_GetModuleByDef(type, &_randommodule)))
103 : :
104 : : typedef struct {
105 : : PyObject_HEAD
106 : : int index;
107 : : uint32_t state[N];
108 : : } RandomObject;
109 : :
110 : :
111 : : #include "clinic/_randommodule.c.h"
112 : :
113 : : /*[clinic input]
114 : : module _random
115 : : class _random.Random "RandomObject *" "_randomstate_type(type)->Random_Type"
116 : : [clinic start generated code]*/
117 : : /*[clinic end generated code: output=da39a3ee5e6b4b0d input=70a2c99619474983]*/
118 : :
119 : : /* Random methods */
120 : :
121 : :
122 : : /* generates a random number on [0,0xffffffff]-interval */
123 : : static uint32_t
124 : 39864878 : genrand_uint32(RandomObject *self)
125 : : {
126 : : uint32_t y;
127 : : static const uint32_t mag01[2] = {0x0U, MATRIX_A};
128 : : /* mag01[x] = x * MATRIX_A for x=0,1 */
129 : : uint32_t *mt;
130 : :
131 : 39864878 : mt = self->state;
132 [ + + ]: 39864878 : if (self->index >= N) { /* generate N words at one time */
133 : : int kk;
134 : :
135 [ + + ]: 14728800 : for (kk=0;kk<N-M;kk++) {
136 : 14664200 : y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
137 : 14664200 : mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1U];
138 : : }
139 [ + + ]: 25646200 : for (;kk<N-1;kk++) {
140 : 25581600 : y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
141 : 25581600 : mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1U];
142 : : }
143 : 64600 : y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK);
144 : 64600 : mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1U];
145 : :
146 : 64600 : self->index = 0;
147 : : }
148 : :
149 : 39864878 : y = mt[self->index++];
150 : 39864878 : y ^= (y >> 11);
151 : 39864878 : y ^= (y << 7) & 0x9d2c5680U;
152 : 39864878 : y ^= (y << 15) & 0xefc60000U;
153 : 39864878 : y ^= (y >> 18);
154 : 39864878 : return y;
155 : : }
156 : :
157 : : /* random_random is the function named genrand_res53 in the original code;
158 : : * generates a random number on [0,1) with 53-bit resolution; note that
159 : : * 9007199254740992 == 2**53; I assume they're spelling "/2**53" as
160 : : * multiply-by-reciprocal in the (likely vain) hope that the compiler will
161 : : * optimize the division away at compile-time. 67108864 is 2**26. In
162 : : * effect, a contains 27 random bits shifted left 26, and b fills in the
163 : : * lower 26 bits of the 53-bit numerator.
164 : : * The original code credited Isaku Wada for this algorithm, 2002/01/09.
165 : : */
166 : :
167 : : /*[clinic input]
168 : : _random.Random.random
169 : :
170 : : self: self(type="RandomObject *")
171 : :
172 : : random() -> x in the interval [0, 1).
173 : : [clinic start generated code]*/
174 : :
175 : : static PyObject *
176 : 9557391 : _random_Random_random_impl(RandomObject *self)
177 : : /*[clinic end generated code: output=117ff99ee53d755c input=afb2a59cbbb00349]*/
178 : : {
179 : 9557391 : uint32_t a=genrand_uint32(self)>>5, b=genrand_uint32(self)>>6;
180 : 9557391 : return PyFloat_FromDouble((a*67108864.0+b)*(1.0/9007199254740992.0));
181 : : }
182 : :
183 : : /* initializes mt[N] with a seed */
184 : : static void
185 : 1876 : init_genrand(RandomObject *self, uint32_t s)
186 : : {
187 : : int mti;
188 : : uint32_t *mt;
189 : :
190 : 1876 : mt = self->state;
191 : 1876 : mt[0]= s;
192 [ + + ]: 1170624 : for (mti=1; mti<N; mti++) {
193 : 1168748 : mt[mti] =
194 : 1168748 : (1812433253U * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti);
195 : : /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
196 : : /* In the previous versions, MSBs of the seed affect */
197 : : /* only MSBs of the array mt[]. */
198 : : /* 2002/01/09 modified by Makoto Matsumoto */
199 : : }
200 : 1876 : self->index = mti;
201 : 1876 : return;
202 : : }
203 : :
204 : : /* initialize by an array with array-length */
205 : : /* init_key is the array for initializing keys */
206 : : /* key_length is its length */
207 : : static void
208 : 1876 : init_by_array(RandomObject *self, uint32_t init_key[], size_t key_length)
209 : : {
210 : : size_t i, j, k; /* was signed in the original code. RDH 12/16/2002 */
211 : : uint32_t *mt;
212 : :
213 : 1876 : mt = self->state;
214 : 1876 : init_genrand(self, 19650218U);
215 : 1876 : i=1; j=0;
216 : 1876 : k = (N>key_length ? N : key_length);
217 [ + + ]: 1174376 : for (; k; k--) {
218 : 1172500 : mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525U))
219 : 1172500 : + init_key[j] + (uint32_t)j; /* non linear */
220 : 1172500 : i++; j++;
221 [ + + ]: 1172500 : if (i>=N) { mt[0] = mt[N-1]; i=1; }
222 [ + + ]: 1172500 : if (j>=key_length) j=0;
223 : : }
224 [ + + ]: 1170624 : for (k=N-1; k; k--) {
225 : 1168748 : mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941U))
226 : 1168748 : - (uint32_t)i; /* non linear */
227 : 1168748 : i++;
228 [ + + ]: 1168748 : if (i>=N) { mt[0] = mt[N-1]; i=1; }
229 : : }
230 : :
231 : 1876 : mt[0] = 0x80000000U; /* MSB is 1; assuring non-zero initial array */
232 : 1876 : }
233 : :
234 : : /*
235 : : * The rest is Python-specific code, neither part of, nor derived from, the
236 : : * Twister download.
237 : : */
238 : :
239 : : static int
240 : 1757 : random_seed_urandom(RandomObject *self)
241 : : {
242 : : uint32_t key[N];
243 : :
244 [ - + ]: 1757 : if (_PyOS_URandomNonblock(key, sizeof(key)) < 0) {
245 : 0 : return -1;
246 : : }
247 : 1757 : init_by_array(self, key, Py_ARRAY_LENGTH(key));
248 : 1757 : return 0;
249 : : }
250 : :
251 : : static void
252 : 0 : random_seed_time_pid(RandomObject *self)
253 : : {
254 : : _PyTime_t now;
255 : : uint32_t key[5];
256 : :
257 : 0 : now = _PyTime_GetSystemClock();
258 : 0 : key[0] = (uint32_t)(now & 0xffffffffU);
259 : 0 : key[1] = (uint32_t)(now >> 32);
260 : :
261 : : #ifdef HAVE_GETPID
262 : 0 : key[2] = (uint32_t)getpid();
263 : : #else
264 : : key[2] = 0;
265 : : #endif
266 : :
267 : 0 : now = _PyTime_GetMonotonicClock();
268 : 0 : key[3] = (uint32_t)(now & 0xffffffffU);
269 : 0 : key[4] = (uint32_t)(now >> 32);
270 : :
271 : 0 : init_by_array(self, key, Py_ARRAY_LENGTH(key));
272 : 0 : }
273 : :
274 : : static int
275 : 1876 : random_seed(RandomObject *self, PyObject *arg)
276 : : {
277 : 1876 : int result = -1; /* guilty until proved innocent */
278 : 1876 : PyObject *n = NULL;
279 : 1876 : uint32_t *key = NULL;
280 : : size_t bits, keyused;
281 : : int res;
282 : :
283 [ + + + + ]: 1876 : if (arg == NULL || arg == Py_None) {
284 [ - + ]: 1757 : if (random_seed_urandom(self) < 0) {
285 : 0 : PyErr_Clear();
286 : :
287 : : /* Reading system entropy failed, fall back on the worst entropy:
288 : : use the current time and process identifier. */
289 : 0 : random_seed_time_pid(self);
290 : : }
291 : 1757 : return 0;
292 : : }
293 : :
294 : : /* This algorithm relies on the number being unsigned.
295 : : * So: if the arg is a PyLong, use its absolute value.
296 : : * Otherwise use its hash value, cast to unsigned.
297 : : */
298 [ + + ]: 119 : if (PyLong_CheckExact(arg)) {
299 : 112 : n = PyNumber_Absolute(arg);
300 [ + + ]: 7 : } else if (PyLong_Check(arg)) {
301 : : /* Calling int.__abs__() prevents calling arg.__abs__(), which might
302 : : return an invalid value. See issue #31478. */
303 : 5 : _randomstate *state = _randomstate_type(Py_TYPE(self));
304 : 5 : n = PyObject_CallOneArg(state->Long___abs__, arg);
305 : : }
306 : : else {
307 : 2 : Py_hash_t hash = PyObject_Hash(arg);
308 [ - + ]: 2 : if (hash == -1)
309 : 0 : goto Done;
310 : 2 : n = PyLong_FromSize_t((size_t)hash);
311 : : }
312 [ - + ]: 119 : if (n == NULL)
313 : 0 : goto Done;
314 : :
315 : : /* Now split n into 32-bit chunks, from the right. */
316 : 119 : bits = _PyLong_NumBits(n);
317 [ - + - - ]: 119 : if (bits == (size_t)-1 && PyErr_Occurred())
318 : 0 : goto Done;
319 : :
320 : : /* Figure out how many 32-bit chunks this gives us. */
321 [ + + ]: 119 : keyused = bits == 0 ? 1 : (bits - 1) / 32 + 1;
322 : :
323 : : /* Convert seed to byte sequence. */
324 : 119 : key = (uint32_t *)PyMem_Malloc((size_t)4 * keyused);
325 [ - + ]: 119 : if (key == NULL) {
326 : : PyErr_NoMemory();
327 : 0 : goto Done;
328 : : }
329 : 119 : res = _PyLong_AsByteArray((PyLongObject *)n,
330 : : (unsigned char *)key, keyused * 4,
331 : : PY_LITTLE_ENDIAN,
332 : : 0); /* unsigned */
333 [ - + ]: 119 : if (res == -1) {
334 : 0 : goto Done;
335 : : }
336 : :
337 : : #if PY_BIG_ENDIAN
338 : : {
339 : : size_t i, j;
340 : : /* Reverse an array. */
341 : : for (i = 0, j = keyused - 1; i < j; i++, j--) {
342 : : uint32_t tmp = key[i];
343 : : key[i] = key[j];
344 : : key[j] = tmp;
345 : : }
346 : : }
347 : : #endif
348 : 119 : init_by_array(self, key, keyused);
349 : :
350 : 119 : result = 0;
351 : :
352 : 119 : Done:
353 : 119 : Py_XDECREF(n);
354 : 119 : PyMem_Free(key);
355 : 119 : return result;
356 : : }
357 : :
358 : : /*[clinic input]
359 : : _random.Random.seed
360 : :
361 : : self: self(type="RandomObject *")
362 : : n: object = None
363 : : /
364 : :
365 : : seed([n]) -> None.
366 : :
367 : : Defaults to use urandom and falls back to a combination
368 : : of the current time and the process identifier.
369 : : [clinic start generated code]*/
370 : :
371 : : static PyObject *
372 : 1868 : _random_Random_seed_impl(RandomObject *self, PyObject *n)
373 : : /*[clinic end generated code: output=0fad1e16ba883681 input=78d6ef0d52532a54]*/
374 : : {
375 [ - + ]: 1868 : if (random_seed(self, n) < 0) {
376 : 0 : return NULL;
377 : : }
378 : 1868 : Py_RETURN_NONE;
379 : : }
380 : :
381 : : /*[clinic input]
382 : : _random.Random.getstate
383 : :
384 : : self: self(type="RandomObject *")
385 : :
386 : : getstate() -> tuple containing the current state.
387 : : [clinic start generated code]*/
388 : :
389 : : static PyObject *
390 : 11 : _random_Random_getstate_impl(RandomObject *self)
391 : : /*[clinic end generated code: output=bf6cef0c092c7180 input=b937a487928c0e89]*/
392 : : {
393 : : PyObject *state;
394 : : PyObject *element;
395 : : int i;
396 : :
397 : 11 : state = PyTuple_New(N+1);
398 [ - + ]: 11 : if (state == NULL)
399 : 0 : return NULL;
400 [ + + ]: 6875 : for (i=0; i<N ; i++) {
401 : 6864 : element = PyLong_FromUnsignedLong(self->state[i]);
402 [ - + ]: 6864 : if (element == NULL)
403 : 0 : goto Fail;
404 : 6864 : PyTuple_SET_ITEM(state, i, element);
405 : : }
406 : 11 : element = PyLong_FromLong((long)(self->index));
407 [ - + ]: 11 : if (element == NULL)
408 : 0 : goto Fail;
409 : 11 : PyTuple_SET_ITEM(state, i, element);
410 : 11 : return state;
411 : :
412 : 0 : Fail:
413 : 0 : Py_DECREF(state);
414 : 0 : return NULL;
415 : : }
416 : :
417 : :
418 : : /*[clinic input]
419 : : _random.Random.setstate
420 : :
421 : : self: self(type="RandomObject *")
422 : : state: object
423 : : /
424 : :
425 : : setstate(state) -> None. Restores generator state.
426 : : [clinic start generated code]*/
427 : :
428 : : static PyObject *
429 : 17 : _random_Random_setstate(RandomObject *self, PyObject *state)
430 : : /*[clinic end generated code: output=fd1c3cd0037b6681 input=b3b4efbb1bc66af8]*/
431 : : {
432 : : int i;
433 : : unsigned long element;
434 : : long index;
435 : : uint32_t new_state[N];
436 : :
437 [ - + ]: 17 : if (!PyTuple_Check(state)) {
438 : 0 : PyErr_SetString(PyExc_TypeError,
439 : : "state vector must be a tuple");
440 : 0 : return NULL;
441 : : }
442 [ + + ]: 17 : if (PyTuple_Size(state) != N+1) {
443 : 1 : PyErr_SetString(PyExc_ValueError,
444 : : "state vector is the wrong size");
445 : 1 : return NULL;
446 : : }
447 : :
448 [ + + ]: 10000 : for (i=0; i<N ; i++) {
449 : 9984 : element = PyLong_AsUnsignedLong(PyTuple_GET_ITEM(state, i));
450 [ - + - - ]: 9984 : if (element == (unsigned long)-1 && PyErr_Occurred())
451 : 0 : return NULL;
452 : 9984 : new_state[i] = (uint32_t)element;
453 : : }
454 : :
455 : 16 : index = PyLong_AsLong(PyTuple_GET_ITEM(state, i));
456 [ - + - - ]: 16 : if (index == -1 && PyErr_Occurred())
457 : 0 : return NULL;
458 [ + - + + ]: 16 : if (index < 0 || index > N) {
459 : 2 : PyErr_SetString(PyExc_ValueError, "invalid state");
460 : 2 : return NULL;
461 : : }
462 : 14 : self->index = (int)index;
463 [ + + ]: 8750 : for (i = 0; i < N; i++)
464 : 8736 : self->state[i] = new_state[i];
465 : :
466 : 14 : Py_RETURN_NONE;
467 : : }
468 : :
469 : : /*[clinic input]
470 : :
471 : : _random.Random.getrandbits
472 : :
473 : : self: self(type="RandomObject *")
474 : : k: int
475 : : /
476 : :
477 : : getrandbits(k) -> x. Generates an int with k random bits.
478 : : [clinic start generated code]*/
479 : :
480 : : static PyObject *
481 : 6978886 : _random_Random_getrandbits_impl(RandomObject *self, int k)
482 : : /*[clinic end generated code: output=b402f82a2158887f input=8c0e6396dd176fc0]*/
483 : : {
484 : : int i, words;
485 : : uint32_t r;
486 : : uint32_t *wordarray;
487 : : PyObject *result;
488 : :
489 [ + + ]: 6978886 : if (k < 0) {
490 : 2 : PyErr_SetString(PyExc_ValueError,
491 : : "number of bits must be non-negative");
492 : 2 : return NULL;
493 : : }
494 : :
495 [ + + ]: 6978884 : if (k == 0)
496 : 5 : return PyLong_FromLong(0);
497 : :
498 [ + + ]: 6978879 : if (k <= 32) /* Fast path */
499 : 6278335 : return PyLong_FromUnsignedLong(genrand_uint32(self) >> (32 - k));
500 : :
501 : 700544 : words = (k - 1) / 32 + 1;
502 : 700544 : wordarray = (uint32_t *)PyMem_Malloc(words * 4);
503 [ - + ]: 700544 : if (wordarray == NULL) {
504 : : PyErr_NoMemory();
505 : 0 : return NULL;
506 : : }
507 : :
508 : : /* Fill-out bits of long integer, by 32-bit words, from least significant
509 : : to most significant. */
510 : : #if PY_LITTLE_ENDIAN
511 [ + + ]: 15172305 : for (i = 0; i < words; i++, k -= 32)
512 : : #else
513 : : for (i = words - 1; i >= 0; i--, k -= 32)
514 : : #endif
515 : : {
516 : 14471761 : r = genrand_uint32(self);
517 [ + + ]: 14471761 : if (k < 32)
518 : 622989 : r >>= (32 - k); /* Drop least significant bits */
519 : 14471761 : wordarray[i] = r;
520 : : }
521 : :
522 : 700544 : result = _PyLong_FromByteArray((unsigned char *)wordarray, words * 4,
523 : : PY_LITTLE_ENDIAN, 0 /* unsigned */);
524 : 700544 : PyMem_Free(wordarray);
525 : 700544 : return result;
526 : : }
527 : :
528 : : static int
529 : 8 : random_init(RandomObject *self, PyObject *args, PyObject *kwds)
530 : : {
531 : 8 : PyObject *arg = NULL;
532 : 8 : _randomstate *state = _randomstate_type(Py_TYPE(self));
533 : :
534 [ - + ]: 8 : if ((Py_IS_TYPE(self, (PyTypeObject *)state->Random_Type) ||
535 [ - - - + ]: 8 : Py_TYPE(self)->tp_init == ((PyTypeObject*)state->Random_Type)->tp_init) &&
536 [ # # ]: 0 : !_PyArg_NoKeywords("Random", kwds)) {
537 : 0 : return -1;
538 : : }
539 : :
540 [ - + ]: 8 : if (PyTuple_GET_SIZE(args) > 1) {
541 : 0 : PyErr_SetString(PyExc_TypeError, "Random() requires 0 or 1 argument");
542 : 0 : return -1;
543 : : }
544 : :
545 [ + + ]: 8 : if (PyTuple_GET_SIZE(args) == 1)
546 : 1 : arg = PyTuple_GET_ITEM(args, 0);
547 : :
548 : 8 : return random_seed(self, arg);
549 : : }
550 : :
551 : :
552 : : static PyMethodDef random_methods[] = {
553 : : _RANDOM_RANDOM_RANDOM_METHODDEF
554 : : _RANDOM_RANDOM_SEED_METHODDEF
555 : : _RANDOM_RANDOM_GETSTATE_METHODDEF
556 : : _RANDOM_RANDOM_SETSTATE_METHODDEF
557 : : _RANDOM_RANDOM_GETRANDBITS_METHODDEF
558 : : {NULL, NULL} /* sentinel */
559 : : };
560 : :
561 : : PyDoc_STRVAR(random_doc,
562 : : "Random() -> create a random number generator with its own internal state.");
563 : :
564 : : static PyType_Slot Random_Type_slots[] = {
565 : : {Py_tp_doc, (void *)random_doc},
566 : : {Py_tp_methods, random_methods},
567 : : {Py_tp_new, PyType_GenericNew},
568 : : {Py_tp_init, random_init},
569 : : {Py_tp_free, PyObject_Free},
570 : : {0, 0},
571 : : };
572 : :
573 : : static PyType_Spec Random_Type_spec = {
574 : : "_random.Random",
575 : : sizeof(RandomObject),
576 : : 0,
577 : : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
578 : : Random_Type_slots
579 : : };
580 : :
581 : : PyDoc_STRVAR(module_doc,
582 : : "Module implements the Mersenne Twister random number generator.");
583 : :
584 : : static int
585 : 1105 : _random_exec(PyObject *module)
586 : : {
587 : 1105 : _randomstate *state = get_random_state(module);
588 : :
589 : 1105 : state->Random_Type = PyType_FromModuleAndSpec(
590 : : module, &Random_Type_spec, NULL);
591 [ - + ]: 1105 : if (state->Random_Type == NULL) {
592 : 0 : return -1;
593 : : }
594 [ - + ]: 1105 : if (PyModule_AddType(module, (PyTypeObject *)state->Random_Type) < 0) {
595 : 0 : return -1;
596 : : }
597 : :
598 : : /* Look up and save int.__abs__, which is needed in random_seed(). */
599 : 1105 : PyObject *longval = PyLong_FromLong(0);
600 [ - + ]: 1105 : if (longval == NULL) {
601 : 0 : return -1;
602 : : }
603 : :
604 : 1105 : PyObject *longtype = PyObject_Type(longval);
605 : 1105 : Py_DECREF(longval);
606 [ - + ]: 1105 : if (longtype == NULL) {
607 : 0 : return -1;
608 : : }
609 : :
610 : 1105 : state->Long___abs__ = PyObject_GetAttrString(longtype, "__abs__");
611 : 1105 : Py_DECREF(longtype);
612 [ - + ]: 1105 : if (state->Long___abs__ == NULL) {
613 : 0 : return -1;
614 : : }
615 : 1105 : return 0;
616 : : }
617 : :
618 : : static PyModuleDef_Slot _random_slots[] = {
619 : : {Py_mod_exec, _random_exec},
620 : : {0, NULL}
621 : : };
622 : :
623 : : static int
624 : 40734 : _random_traverse(PyObject *module, visitproc visit, void *arg)
625 : : {
626 [ + - - + ]: 40734 : Py_VISIT(get_random_state(module)->Random_Type);
627 : 40734 : return 0;
628 : : }
629 : :
630 : : static int
631 : 2174 : _random_clear(PyObject *module)
632 : : {
633 [ + + ]: 2174 : Py_CLEAR(get_random_state(module)->Random_Type);
634 [ + + ]: 2174 : Py_CLEAR(get_random_state(module)->Long___abs__);
635 : 2174 : return 0;
636 : : }
637 : :
638 : : static void
639 : 1104 : _random_free(void *module)
640 : : {
641 : 1104 : _random_clear((PyObject *)module);
642 : 1104 : }
643 : :
644 : : static struct PyModuleDef _randommodule = {
645 : : PyModuleDef_HEAD_INIT,
646 : : "_random",
647 : : module_doc,
648 : : sizeof(_randomstate),
649 : : NULL,
650 : : _random_slots,
651 : : _random_traverse,
652 : : _random_clear,
653 : : _random_free,
654 : : };
655 : :
656 : : PyMODINIT_FUNC
657 : 1105 : PyInit__random(void)
658 : : {
659 : 1105 : return PyModuleDef_Init(&_randommodule);
660 : : }
|