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 | #include "Python.h" |
70 | #include "pycore_moduleobject.h" // _PyModule_GetState() |
71 | #ifdef HAVE_PROCESS_H |
72 | # include <process.h> // getpid() |
73 | #endif |
74 | |
75 | /* Period parameters -- These are all magic. Don't change. */ |
76 | #define N 624 |
77 | #define M 397 |
78 | #define MATRIX_A 0x9908b0dfU /* constant vector a */ |
79 | #define UPPER_MASK 0x80000000U /* most significant w-r bits */ |
80 | #define LOWER_MASK 0x7fffffffU /* least significant r bits */ |
81 | |
82 | typedef struct { |
83 | PyObject *Random_Type; |
84 | PyObject *Long___abs__; |
85 | } _randomstate; |
86 | |
87 | static inline _randomstate* |
88 | get_random_state(PyObject *module) |
89 | { |
90 | void *state = _PyModule_GetState(module); |
91 | assert(state != NULL); |
92 | return (_randomstate *)state; |
93 | } |
94 | |
95 | static struct PyModuleDef _randommodule; |
96 | |
97 | #define _randomstate_type(type) \ |
98 | (get_random_state(_PyType_GetModuleByDef(type, &_randommodule))) |
99 | |
100 | typedef struct { |
101 | PyObject_HEAD |
102 | int index; |
103 | uint32_t state[N]; |
104 | } RandomObject; |
105 | |
106 | |
107 | #include "clinic/_randommodule.c.h" |
108 | |
109 | /*[clinic input] |
110 | module _random |
111 | class _random.Random "RandomObject *" "_randomstate_type(type)->Random_Type" |
112 | [clinic start generated code]*/ |
113 | /*[clinic end generated code: output=da39a3ee5e6b4b0d input=70a2c99619474983]*/ |
114 | |
115 | /* Random methods */ |
116 | |
117 | |
118 | /* generates a random number on [0,0xffffffff]-interval */ |
119 | static uint32_t |
120 | genrand_uint32(RandomObject *self) |
121 | { |
122 | uint32_t y; |
123 | static const uint32_t mag01[2] = {0x0U, MATRIX_A}; |
124 | /* mag01[x] = x * MATRIX_A for x=0,1 */ |
125 | uint32_t *mt; |
126 | |
127 | mt = self->state; |
128 | if (self->index >= N) { /* generate N words at one time */ |
129 | int kk; |
130 | |
131 | for (kk=0;kk<N-M;kk++) { |
132 | y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK); |
133 | mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1U]; |
134 | } |
135 | for (;kk<N-1;kk++) { |
136 | y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK); |
137 | mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1U]; |
138 | } |
139 | y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK); |
140 | mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1U]; |
141 | |
142 | self->index = 0; |
143 | } |
144 | |
145 | y = mt[self->index++]; |
146 | y ^= (y >> 11); |
147 | y ^= (y << 7) & 0x9d2c5680U; |
148 | y ^= (y << 15) & 0xefc60000U; |
149 | y ^= (y >> 18); |
150 | return y; |
151 | } |
152 | |
153 | /* random_random is the function named genrand_res53 in the original code; |
154 | * generates a random number on [0,1) with 53-bit resolution; note that |
155 | * 9007199254740992 == 2**53; I assume they're spelling "/2**53" as |
156 | * multiply-by-reciprocal in the (likely vain) hope that the compiler will |
157 | * optimize the division away at compile-time. 67108864 is 2**26. In |
158 | * effect, a contains 27 random bits shifted left 26, and b fills in the |
159 | * lower 26 bits of the 53-bit numerator. |
160 | * The original code credited Isaku Wada for this algorithm, 2002/01/09. |
161 | */ |
162 | |
163 | /*[clinic input] |
164 | _random.Random.random |
165 | |
166 | self: self(type="RandomObject *") |
167 | |
168 | random() -> x in the interval [0, 1). |
169 | [clinic start generated code]*/ |
170 | |
171 | static PyObject * |
172 | _random_Random_random_impl(RandomObject *self) |
173 | /*[clinic end generated code: output=117ff99ee53d755c input=afb2a59cbbb00349]*/ |
174 | { |
175 | uint32_t a=genrand_uint32(self)>>5, b=genrand_uint32(self)>>6; |
176 | return PyFloat_FromDouble((a*67108864.0+b)*(1.0/9007199254740992.0)); |
177 | } |
178 | |
179 | /* initializes mt[N] with a seed */ |
180 | static void |
181 | init_genrand(RandomObject *self, uint32_t s) |
182 | { |
183 | int mti; |
184 | uint32_t *mt; |
185 | |
186 | mt = self->state; |
187 | mt[0]= s; |
188 | for (mti=1; mti<N; mti++) { |
189 | mt[mti] = |
190 | (1812433253U * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti); |
191 | /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */ |
192 | /* In the previous versions, MSBs of the seed affect */ |
193 | /* only MSBs of the array mt[]. */ |
194 | /* 2002/01/09 modified by Makoto Matsumoto */ |
195 | } |
196 | self->index = mti; |
197 | return; |
198 | } |
199 | |
200 | /* initialize by an array with array-length */ |
201 | /* init_key is the array for initializing keys */ |
202 | /* key_length is its length */ |
203 | static void |
204 | init_by_array(RandomObject *self, uint32_t init_key[], size_t key_length) |
205 | { |
206 | size_t i, j, k; /* was signed in the original code. RDH 12/16/2002 */ |
207 | uint32_t *mt; |
208 | |
209 | mt = self->state; |
210 | init_genrand(self, 19650218U); |
211 | i=1; j=0; |
212 | k = (N>key_length ? N : key_length); |
213 | for (; k; k--) { |
214 | mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525U)) |
215 | + init_key[j] + (uint32_t)j; /* non linear */ |
216 | i++; j++; |
217 | if (i>=N) { mt[0] = mt[N-1]; i=1; } |
218 | if (j>=key_length) j=0; |
219 | } |
220 | for (k=N-1; k; k--) { |
221 | mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941U)) |
222 | - (uint32_t)i; /* non linear */ |
223 | i++; |
224 | if (i>=N) { mt[0] = mt[N-1]; i=1; } |
225 | } |
226 | |
227 | mt[0] = 0x80000000U; /* MSB is 1; assuring non-zero initial array */ |
228 | } |
229 | |
230 | /* |
231 | * The rest is Python-specific code, neither part of, nor derived from, the |
232 | * Twister download. |
233 | */ |
234 | |
235 | static int |
236 | random_seed_urandom(RandomObject *self) |
237 | { |
238 | uint32_t key[N]; |
239 | |
240 | if (_PyOS_URandomNonblock(key, sizeof(key)) < 0) { |
241 | return -1; |
242 | } |
243 | init_by_array(self, key, Py_ARRAY_LENGTH(key)); |
244 | return 0; |
245 | } |
246 | |
247 | static void |
248 | random_seed_time_pid(RandomObject *self) |
249 | { |
250 | _PyTime_t now; |
251 | uint32_t key[5]; |
252 | |
253 | now = _PyTime_GetSystemClock(); |
254 | key[0] = (uint32_t)(now & 0xffffffffU); |
255 | key[1] = (uint32_t)(now >> 32); |
256 | |
257 | key[2] = (uint32_t)getpid(); |
258 | |
259 | now = _PyTime_GetMonotonicClock(); |
260 | key[3] = (uint32_t)(now & 0xffffffffU); |
261 | key[4] = (uint32_t)(now >> 32); |
262 | |
263 | init_by_array(self, key, Py_ARRAY_LENGTH(key)); |
264 | } |
265 | |
266 | static PyObject * |
267 | random_seed(RandomObject *self, PyObject *arg) |
268 | { |
269 | PyObject *result = NULL; /* guilty until proved innocent */ |
270 | PyObject *n = NULL; |
271 | uint32_t *key = NULL; |
272 | size_t bits, keyused; |
273 | int res; |
274 | |
275 | if (arg == NULL || arg == Py_None) { |
276 | if (random_seed_urandom(self) < 0) { |
277 | PyErr_Clear(); |
278 | |
279 | /* Reading system entropy failed, fall back on the worst entropy: |
280 | use the current time and process identifier. */ |
281 | random_seed_time_pid(self); |
282 | } |
283 | Py_RETURN_NONE; |
284 | } |
285 | |
286 | /* This algorithm relies on the number being unsigned. |
287 | * So: if the arg is a PyLong, use its absolute value. |
288 | * Otherwise use its hash value, cast to unsigned. |
289 | */ |
290 | if (PyLong_CheckExact(arg)) { |
291 | n = PyNumber_Absolute(arg); |
292 | } else if (PyLong_Check(arg)) { |
293 | /* Calling int.__abs__() prevents calling arg.__abs__(), which might |
294 | return an invalid value. See issue #31478. */ |
295 | _randomstate *state = _randomstate_type(Py_TYPE(self)); |
296 | n = PyObject_CallOneArg(state->Long___abs__, arg); |
297 | } |
298 | else { |
299 | Py_hash_t hash = PyObject_Hash(arg); |
300 | if (hash == -1) |
301 | goto Done; |
302 | n = PyLong_FromSize_t((size_t)hash); |
303 | } |
304 | if (n == NULL) |
305 | goto Done; |
306 | |
307 | /* Now split n into 32-bit chunks, from the right. */ |
308 | bits = _PyLong_NumBits(n); |
309 | if (bits == (size_t)-1 && PyErr_Occurred()) |
310 | goto Done; |
311 | |
312 | /* Figure out how many 32-bit chunks this gives us. */ |
313 | keyused = bits == 0 ? 1 : (bits - 1) / 32 + 1; |
314 | |
315 | /* Convert seed to byte sequence. */ |
316 | key = (uint32_t *)PyMem_Malloc((size_t)4 * keyused); |
317 | if (key == NULL) { |
318 | PyErr_NoMemory(); |
319 | goto Done; |
320 | } |
321 | res = _PyLong_AsByteArray((PyLongObject *)n, |
322 | (unsigned char *)key, keyused * 4, |
323 | PY_LITTLE_ENDIAN, |
324 | 0); /* unsigned */ |
325 | if (res == -1) { |
326 | goto Done; |
327 | } |
328 | |
329 | #if PY_BIG_ENDIAN |
330 | { |
331 | size_t i, j; |
332 | /* Reverse an array. */ |
333 | for (i = 0, j = keyused - 1; i < j; i++, j--) { |
334 | uint32_t tmp = key[i]; |
335 | key[i] = key[j]; |
336 | key[j] = tmp; |
337 | } |
338 | } |
339 | #endif |
340 | init_by_array(self, key, keyused); |
341 | |
342 | Py_INCREF(Py_None); |
343 | result = Py_None; |
344 | |
345 | Done: |
346 | Py_XDECREF(n); |
347 | PyMem_Free(key); |
348 | return result; |
349 | } |
350 | |
351 | /*[clinic input] |
352 | _random.Random.seed |
353 | |
354 | self: self(type="RandomObject *") |
355 | n: object = None |
356 | / |
357 | |
358 | seed([n]) -> None. |
359 | |
360 | Defaults to use urandom and falls back to a combination |
361 | of the current time and the process identifier. |
362 | [clinic start generated code]*/ |
363 | |
364 | static PyObject * |
365 | _random_Random_seed_impl(RandomObject *self, PyObject *n) |
366 | /*[clinic end generated code: output=0fad1e16ba883681 input=78d6ef0d52532a54]*/ |
367 | { |
368 | return random_seed(self, n); |
369 | } |
370 | |
371 | /*[clinic input] |
372 | _random.Random.getstate |
373 | |
374 | self: self(type="RandomObject *") |
375 | |
376 | getstate() -> tuple containing the current state. |
377 | [clinic start generated code]*/ |
378 | |
379 | static PyObject * |
380 | _random_Random_getstate_impl(RandomObject *self) |
381 | /*[clinic end generated code: output=bf6cef0c092c7180 input=b937a487928c0e89]*/ |
382 | { |
383 | PyObject *state; |
384 | PyObject *element; |
385 | int i; |
386 | |
387 | state = PyTuple_New(N+1); |
388 | if (state == NULL) |
389 | return NULL; |
390 | for (i=0; i<N ; i++) { |
391 | element = PyLong_FromUnsignedLong(self->state[i]); |
392 | if (element == NULL) |
393 | goto Fail; |
394 | PyTuple_SET_ITEM(state, i, element); |
395 | } |
396 | element = PyLong_FromLong((long)(self->index)); |
397 | if (element == NULL) |
398 | goto Fail; |
399 | PyTuple_SET_ITEM(state, i, element); |
400 | return state; |
401 | |
402 | Fail: |
403 | Py_DECREF(state); |
404 | return NULL; |
405 | } |
406 | |
407 | |
408 | /*[clinic input] |
409 | _random.Random.setstate |
410 | |
411 | self: self(type="RandomObject *") |
412 | state: object |
413 | / |
414 | |
415 | setstate(state) -> None. Restores generator state. |
416 | [clinic start generated code]*/ |
417 | |
418 | static PyObject * |
419 | _random_Random_setstate(RandomObject *self, PyObject *state) |
420 | /*[clinic end generated code: output=fd1c3cd0037b6681 input=b3b4efbb1bc66af8]*/ |
421 | { |
422 | int i; |
423 | unsigned long element; |
424 | long index; |
425 | uint32_t new_state[N]; |
426 | |
427 | if (!PyTuple_Check(state)) { |
428 | PyErr_SetString(PyExc_TypeError, |
429 | "state vector must be a tuple" ); |
430 | return NULL; |
431 | } |
432 | if (PyTuple_Size(state) != N+1) { |
433 | PyErr_SetString(PyExc_ValueError, |
434 | "state vector is the wrong size" ); |
435 | return NULL; |
436 | } |
437 | |
438 | for (i=0; i<N ; i++) { |
439 | element = PyLong_AsUnsignedLong(PyTuple_GET_ITEM(state, i)); |
440 | if (element == (unsigned long)-1 && PyErr_Occurred()) |
441 | return NULL; |
442 | new_state[i] = (uint32_t)element; |
443 | } |
444 | |
445 | index = PyLong_AsLong(PyTuple_GET_ITEM(state, i)); |
446 | if (index == -1 && PyErr_Occurred()) |
447 | return NULL; |
448 | if (index < 0 || index > N) { |
449 | PyErr_SetString(PyExc_ValueError, "invalid state" ); |
450 | return NULL; |
451 | } |
452 | self->index = (int)index; |
453 | for (i = 0; i < N; i++) |
454 | self->state[i] = new_state[i]; |
455 | |
456 | Py_RETURN_NONE; |
457 | } |
458 | |
459 | /*[clinic input] |
460 | |
461 | _random.Random.getrandbits |
462 | |
463 | self: self(type="RandomObject *") |
464 | k: int |
465 | / |
466 | |
467 | getrandbits(k) -> x. Generates an int with k random bits. |
468 | [clinic start generated code]*/ |
469 | |
470 | static PyObject * |
471 | _random_Random_getrandbits_impl(RandomObject *self, int k) |
472 | /*[clinic end generated code: output=b402f82a2158887f input=8c0e6396dd176fc0]*/ |
473 | { |
474 | int i, words; |
475 | uint32_t r; |
476 | uint32_t *wordarray; |
477 | PyObject *result; |
478 | |
479 | if (k < 0) { |
480 | PyErr_SetString(PyExc_ValueError, |
481 | "number of bits must be non-negative" ); |
482 | return NULL; |
483 | } |
484 | |
485 | if (k == 0) |
486 | return PyLong_FromLong(0); |
487 | |
488 | if (k <= 32) /* Fast path */ |
489 | return PyLong_FromUnsignedLong(genrand_uint32(self) >> (32 - k)); |
490 | |
491 | words = (k - 1) / 32 + 1; |
492 | wordarray = (uint32_t *)PyMem_Malloc(words * 4); |
493 | if (wordarray == NULL) { |
494 | PyErr_NoMemory(); |
495 | return NULL; |
496 | } |
497 | |
498 | /* Fill-out bits of long integer, by 32-bit words, from least significant |
499 | to most significant. */ |
500 | #if PY_LITTLE_ENDIAN |
501 | for (i = 0; i < words; i++, k -= 32) |
502 | #else |
503 | for (i = words - 1; i >= 0; i--, k -= 32) |
504 | #endif |
505 | { |
506 | r = genrand_uint32(self); |
507 | if (k < 32) |
508 | r >>= (32 - k); /* Drop least significant bits */ |
509 | wordarray[i] = r; |
510 | } |
511 | |
512 | result = _PyLong_FromByteArray((unsigned char *)wordarray, words * 4, |
513 | PY_LITTLE_ENDIAN, 0 /* unsigned */); |
514 | PyMem_Free(wordarray); |
515 | return result; |
516 | } |
517 | |
518 | static PyObject * |
519 | random_new(PyTypeObject *type, PyObject *args, PyObject *kwds) |
520 | { |
521 | RandomObject *self; |
522 | PyObject *tmp; |
523 | PyObject *arg = NULL; |
524 | _randomstate *state = _randomstate_type(type); |
525 | |
526 | if (type == (PyTypeObject*)state->Random_Type && |
527 | !_PyArg_NoKeywords("Random()" , kwds)) { |
528 | return NULL; |
529 | } |
530 | |
531 | self = (RandomObject *)PyType_GenericAlloc(type, 0); |
532 | if (self == NULL) |
533 | return NULL; |
534 | |
535 | if (PyTuple_GET_SIZE(args) > 1) { |
536 | PyErr_SetString(PyExc_TypeError, "Random() requires 0 or 1 argument" ); |
537 | return NULL; |
538 | } |
539 | |
540 | if (PyTuple_GET_SIZE(args) == 1) |
541 | arg = PyTuple_GET_ITEM(args, 0); |
542 | |
543 | tmp = random_seed(self, arg); |
544 | if (tmp == NULL) { |
545 | Py_DECREF(self); |
546 | return NULL; |
547 | } |
548 | Py_DECREF(tmp); |
549 | |
550 | return (PyObject *)self; |
551 | } |
552 | |
553 | |
554 | static PyMethodDef random_methods[] = { |
555 | _RANDOM_RANDOM_RANDOM_METHODDEF |
556 | _RANDOM_RANDOM_SEED_METHODDEF |
557 | _RANDOM_RANDOM_GETSTATE_METHODDEF |
558 | _RANDOM_RANDOM_SETSTATE_METHODDEF |
559 | _RANDOM_RANDOM_GETRANDBITS_METHODDEF |
560 | {NULL, NULL} /* sentinel */ |
561 | }; |
562 | |
563 | PyDoc_STRVAR(random_doc, |
564 | "Random() -> create a random number generator with its own internal state." ); |
565 | |
566 | static PyType_Slot Random_Type_slots[] = { |
567 | {Py_tp_doc, (void *)random_doc}, |
568 | {Py_tp_methods, random_methods}, |
569 | {Py_tp_new, random_new}, |
570 | {Py_tp_free, PyObject_Free}, |
571 | {0, 0}, |
572 | }; |
573 | |
574 | static PyType_Spec Random_Type_spec = { |
575 | "_random.Random" , |
576 | sizeof(RandomObject), |
577 | 0, |
578 | Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, |
579 | Random_Type_slots |
580 | }; |
581 | |
582 | PyDoc_STRVAR(module_doc, |
583 | "Module implements the Mersenne Twister random number generator." ); |
584 | |
585 | static int |
586 | _random_exec(PyObject *module) |
587 | { |
588 | _randomstate *state = get_random_state(module); |
589 | |
590 | state->Random_Type = PyType_FromModuleAndSpec( |
591 | module, &Random_Type_spec, NULL); |
592 | if (state->Random_Type == NULL) { |
593 | return -1; |
594 | } |
595 | if (PyModule_AddType(module, (PyTypeObject *)state->Random_Type) < 0) { |
596 | return -1; |
597 | } |
598 | |
599 | /* Look up and save int.__abs__, which is needed in random_seed(). */ |
600 | PyObject *longval = PyLong_FromLong(0); |
601 | if (longval == NULL) { |
602 | return -1; |
603 | } |
604 | |
605 | PyObject *longtype = PyObject_Type(longval); |
606 | Py_DECREF(longval); |
607 | if (longtype == NULL) { |
608 | return -1; |
609 | } |
610 | |
611 | state->Long___abs__ = PyObject_GetAttrString(longtype, "__abs__" ); |
612 | Py_DECREF(longtype); |
613 | if (state->Long___abs__ == NULL) { |
614 | return -1; |
615 | } |
616 | return 0; |
617 | } |
618 | |
619 | static PyModuleDef_Slot _random_slots[] = { |
620 | {Py_mod_exec, _random_exec}, |
621 | {0, NULL} |
622 | }; |
623 | |
624 | static int |
625 | _random_traverse(PyObject *module, visitproc visit, void *arg) |
626 | { |
627 | Py_VISIT(get_random_state(module)->Random_Type); |
628 | return 0; |
629 | } |
630 | |
631 | static int |
632 | _random_clear(PyObject *module) |
633 | { |
634 | Py_CLEAR(get_random_state(module)->Random_Type); |
635 | Py_CLEAR(get_random_state(module)->Long___abs__); |
636 | return 0; |
637 | } |
638 | |
639 | static void |
640 | _random_free(void *module) |
641 | { |
642 | _random_clear((PyObject *)module); |
643 | } |
644 | |
645 | static struct PyModuleDef _randommodule = { |
646 | PyModuleDef_HEAD_INIT, |
647 | "_random" , |
648 | module_doc, |
649 | sizeof(_randomstate), |
650 | NULL, |
651 | _random_slots, |
652 | _random_traverse, |
653 | _random_clear, |
654 | _random_free, |
655 | }; |
656 | |
657 | PyMODINIT_FUNC |
658 | PyInit__random(void) |
659 | { |
660 | return PyModuleDef_Init(&_randommodule); |
661 | } |
662 | |