|
|
|
@ -5,6 +5,7 @@ import os |
|
|
|
import time |
|
|
|
import pickle |
|
|
|
import warnings |
|
|
|
import logging |
|
|
|
from functools import partial |
|
|
|
from math import log, exp, pi, fsum, sin, factorial |
|
|
|
from test import support |
|
|
|
@ -619,6 +620,16 @@ class MersenneTwister_TestBasicOps(TestBasicOps, unittest.TestCase): |
|
|
|
self.assertRaises(ValueError, self.gen.getrandbits, 0) |
|
|
|
self.assertRaises(ValueError, self.gen.getrandbits, -1) |
|
|
|
|
|
|
|
def test_randrange_uses_getrandbits(self): |
|
|
|
# Verify use of getrandbits by randrange |
|
|
|
# Use same seed as in the cross-platform repeatability test |
|
|
|
# in test_genrandbits above. |
|
|
|
self.gen.seed(1234567) |
|
|
|
# If randrange uses getrandbits, it should pick getrandbits(100) |
|
|
|
# when called with a 100-bits stop argument. |
|
|
|
self.assertEqual(self.gen.randrange(2**99), |
|
|
|
97904845777343510404718956115) |
|
|
|
|
|
|
|
def test_randbelow_logic(self, _log=log, int=int): |
|
|
|
# check bitcount transition points: 2**i and 2**(i+1)-1 |
|
|
|
# show that: k = int(1.001 + _log(n, 2)) |
|
|
|
@ -640,21 +651,22 @@ class MersenneTwister_TestBasicOps(TestBasicOps, unittest.TestCase): |
|
|
|
self.assertEqual(k, numbits) # note the stronger assertion |
|
|
|
self.assertTrue(2**k > n > 2**(k-1)) # note the stronger assertion |
|
|
|
|
|
|
|
@unittest.mock.patch('random.Random.random') |
|
|
|
def test_randbelow_overridden_random(self, random_mock): |
|
|
|
def test_randbelow_without_getrandbits(self): |
|
|
|
# Random._randbelow() can only use random() when the built-in one |
|
|
|
# has been overridden but no new getrandbits() method was supplied. |
|
|
|
random_mock.side_effect = random.SystemRandom().random |
|
|
|
maxsize = 1<<random.BPF |
|
|
|
with warnings.catch_warnings(): |
|
|
|
warnings.simplefilter("ignore", UserWarning) |
|
|
|
# Population range too large (n >= maxsize) |
|
|
|
self.gen._randbelow(maxsize+1, maxsize = maxsize) |
|
|
|
self.gen._randbelow(5640, maxsize = maxsize) |
|
|
|
self.gen._randbelow_without_getrandbits( |
|
|
|
maxsize+1, maxsize=maxsize |
|
|
|
) |
|
|
|
self.gen._randbelow_without_getrandbits(5640, maxsize=maxsize) |
|
|
|
# issue 33203: test that _randbelow raises ValueError on |
|
|
|
# n == 0 also in its getrandbits-independent branch. |
|
|
|
with self.assertRaises(ValueError): |
|
|
|
self.gen._randbelow(0, maxsize=maxsize) |
|
|
|
self.gen._randbelow_without_getrandbits(0, maxsize=maxsize) |
|
|
|
|
|
|
|
# This might be going too far to test a single line, but because of our |
|
|
|
# noble aim of achieving 100% test coverage we need to write a case in |
|
|
|
# which the following line in Random._randbelow() gets executed: |
|
|
|
@ -672,8 +684,10 @@ class MersenneTwister_TestBasicOps(TestBasicOps, unittest.TestCase): |
|
|
|
n = 42 |
|
|
|
epsilon = 0.01 |
|
|
|
limit = (maxsize - (maxsize % n)) / maxsize |
|
|
|
random_mock.side_effect = [limit + epsilon, limit - epsilon] |
|
|
|
self.gen._randbelow(n, maxsize = maxsize) |
|
|
|
with unittest.mock.patch.object(random.Random, 'random') as random_mock: |
|
|
|
random_mock.side_effect = [limit + epsilon, limit - epsilon] |
|
|
|
self.gen._randbelow_without_getrandbits(n, maxsize=maxsize) |
|
|
|
self.assertEqual(random_mock.call_count, 2) |
|
|
|
|
|
|
|
def test_randrange_bug_1590891(self): |
|
|
|
start = 1000000000000 |
|
|
|
@ -926,6 +940,49 @@ class TestDistributions(unittest.TestCase): |
|
|
|
gammavariate_mock.return_value = 0.0 |
|
|
|
self.assertEqual(0.0, random.betavariate(2.71828, 3.14159)) |
|
|
|
|
|
|
|
class TestRandomSubclassing(unittest.TestCase): |
|
|
|
def test_random_subclass_with_kwargs(self): |
|
|
|
# SF bug #1486663 -- this used to erroneously raise a TypeError |
|
|
|
class Subclass(random.Random): |
|
|
|
def __init__(self, newarg=None): |
|
|
|
random.Random.__init__(self) |
|
|
|
Subclass(newarg=1) |
|
|
|
|
|
|
|
def test_subclasses_overriding_methods(self): |
|
|
|
# Subclasses with an overridden random, but only the original |
|
|
|
# getrandbits method should not rely on getrandbits in for randrange, |
|
|
|
# but should use a getrandbits-independent implementation instead. |
|
|
|
|
|
|
|
# subclass providing its own random **and** getrandbits methods |
|
|
|
# like random.SystemRandom does => keep relying on getrandbits for |
|
|
|
# randrange |
|
|
|
class SubClass1(random.Random): |
|
|
|
def random(self): |
|
|
|
return super().random() |
|
|
|
|
|
|
|
def getrandbits(self, n): |
|
|
|
logging.getLogger('getrandbits').info('used getrandbits') |
|
|
|
return super().getrandbits(n) |
|
|
|
with self.assertLogs('getrandbits'): |
|
|
|
SubClass1().randrange(42) |
|
|
|
|
|
|
|
# subclass providing only random => can only use random for randrange |
|
|
|
class SubClass2(random.Random): |
|
|
|
def random(self): |
|
|
|
logging.getLogger('random').info('used random') |
|
|
|
return super().random() |
|
|
|
with self.assertLogs('random'): |
|
|
|
SubClass2().randrange(42) |
|
|
|
|
|
|
|
# subclass defining getrandbits to complement its inherited random |
|
|
|
# => can now rely on getrandbits for randrange again |
|
|
|
class SubClass3(SubClass2): |
|
|
|
def getrandbits(self, n): |
|
|
|
logging.getLogger('getrandbits').info('used getrandbits') |
|
|
|
return super().getrandbits(n) |
|
|
|
with self.assertLogs('getrandbits'): |
|
|
|
SubClass3().randrange(42) |
|
|
|
|
|
|
|
class TestModule(unittest.TestCase): |
|
|
|
def testMagicConstants(self): |
|
|
|
self.assertAlmostEqual(random.NV_MAGICCONST, 1.71552776992141) |
|
|
|
@ -937,13 +994,6 @@ class TestModule(unittest.TestCase): |
|
|
|
# tests validity but not completeness of the __all__ list |
|
|
|
self.assertTrue(set(random.__all__) <= set(dir(random))) |
|
|
|
|
|
|
|
def test_random_subclass_with_kwargs(self): |
|
|
|
# SF bug #1486663 -- this used to erroneously raise a TypeError |
|
|
|
class Subclass(random.Random): |
|
|
|
def __init__(self, newarg=None): |
|
|
|
random.Random.__init__(self) |
|
|
|
Subclass(newarg=1) |
|
|
|
|
|
|
|
@unittest.skipUnless(hasattr(os, "fork"), "fork() required") |
|
|
|
def test_after_fork(self): |
|
|
|
# Test the global Random instance gets reseeded in child |
|
|
|
|