python (3.11.7)

(root)/
lib/
python3.11/
test/
test_random.py
       1  import unittest
       2  import unittest.mock
       3  import random
       4  import os
       5  import time
       6  import pickle
       7  import warnings
       8  import test.support
       9  
      10  from functools import partial
      11  from math import log, exp, pi, fsum, sin, factorial
      12  from test import support
      13  from fractions import Fraction
      14  from collections import abc, Counter
      15  
      16  class ESC[4;38;5;81mTestBasicOps:
      17      # Superclass with tests common to all generators.
      18      # Subclasses must arrange for self.gen to retrieve the Random instance
      19      # to be tested.
      20  
      21      def randomlist(self, n):
      22          """Helper function to make a list of random numbers"""
      23          return [self.gen.random() for i in range(n)]
      24  
      25      def test_autoseed(self):
      26          self.gen.seed()
      27          state1 = self.gen.getstate()
      28          time.sleep(0.1)
      29          self.gen.seed()      # different seeds at different times
      30          state2 = self.gen.getstate()
      31          self.assertNotEqual(state1, state2)
      32  
      33      def test_saverestore(self):
      34          N = 1000
      35          self.gen.seed()
      36          state = self.gen.getstate()
      37          randseq = self.randomlist(N)
      38          self.gen.setstate(state)    # should regenerate the same sequence
      39          self.assertEqual(randseq, self.randomlist(N))
      40  
      41      def test_seedargs(self):
      42          # Seed value with a negative hash.
      43          class ESC[4;38;5;81mMySeed(ESC[4;38;5;149mobject):
      44              def __hash__(self):
      45                  return -1729
      46          for arg in [None, 0, 1, -1, 10**20, -(10**20),
      47                      False, True, 3.14, 'a']:
      48              self.gen.seed(arg)
      49  
      50          for arg in [1+2j, tuple('abc'), MySeed()]:
      51              with self.assertRaises(TypeError):
      52                  self.gen.seed(arg)
      53  
      54          for arg in [list(range(3)), dict(one=1)]:
      55              self.assertRaises(TypeError, self.gen.seed, arg)
      56          self.assertRaises(TypeError, self.gen.seed, 1, 2, 3, 4)
      57          self.assertRaises(TypeError, type(self.gen), [])
      58  
      59      def test_seed_no_mutate_bug_44018(self):
      60          a = bytearray(b'1234')
      61          self.gen.seed(a)
      62          self.assertEqual(a, bytearray(b'1234'))
      63  
      64      @unittest.mock.patch('random._urandom') # os.urandom
      65      def test_seed_when_randomness_source_not_found(self, urandom_mock):
      66          # Random.seed() uses time.time() when an operating system specific
      67          # randomness source is not found. To test this on machines where it
      68          # exists, run the above test, test_seedargs(), again after mocking
      69          # os.urandom() so that it raises the exception expected when the
      70          # randomness source is not available.
      71          urandom_mock.side_effect = NotImplementedError
      72          self.test_seedargs()
      73  
      74      def test_shuffle(self):
      75          shuffle = self.gen.shuffle
      76          lst = []
      77          shuffle(lst)
      78          self.assertEqual(lst, [])
      79          lst = [37]
      80          shuffle(lst)
      81          self.assertEqual(lst, [37])
      82          seqs = [list(range(n)) for n in range(10)]
      83          shuffled_seqs = [list(range(n)) for n in range(10)]
      84          for shuffled_seq in shuffled_seqs:
      85              shuffle(shuffled_seq)
      86          for (seq, shuffled_seq) in zip(seqs, shuffled_seqs):
      87              self.assertEqual(len(seq), len(shuffled_seq))
      88              self.assertEqual(set(seq), set(shuffled_seq))
      89          # The above tests all would pass if the shuffle was a
      90          # no-op. The following non-deterministic test covers that.  It
      91          # asserts that the shuffled sequence of 1000 distinct elements
      92          # must be different from the original one. Although there is
      93          # mathematically a non-zero probability that this could
      94          # actually happen in a genuinely random shuffle, it is
      95          # completely negligible, given that the number of possible
      96          # permutations of 1000 objects is 1000! (factorial of 1000),
      97          # which is considerably larger than the number of atoms in the
      98          # universe...
      99          lst = list(range(1000))
     100          shuffled_lst = list(range(1000))
     101          shuffle(shuffled_lst)
     102          self.assertTrue(lst != shuffled_lst)
     103          shuffle(lst)
     104          self.assertTrue(lst != shuffled_lst)
     105          self.assertRaises(TypeError, shuffle, (1, 2, 3))
     106  
     107      def test_choice(self):
     108          choice = self.gen.choice
     109          with self.assertRaises(IndexError):
     110              choice([])
     111          self.assertEqual(choice([50]), 50)
     112          self.assertIn(choice([25, 75]), [25, 75])
     113  
     114      def test_choice_with_numpy(self):
     115          # Accommodation for NumPy arrays which have disabled __bool__().
     116          # See: https://github.com/python/cpython/issues/100805
     117          choice = self.gen.choice
     118  
     119          class ESC[4;38;5;81mNA(ESC[4;38;5;149mlist):
     120              "Simulate numpy.array() behavior"
     121              def __bool__(self):
     122                  raise RuntimeError
     123  
     124          with self.assertRaises(IndexError):
     125              choice(NA([]))
     126          self.assertEqual(choice(NA([50])), 50)
     127          self.assertIn(choice(NA([25, 75])), [25, 75])
     128  
     129      def test_sample(self):
     130          # For the entire allowable range of 0 <= k <= N, validate that
     131          # the sample is of the correct length and contains only unique items
     132          N = 100
     133          population = range(N)
     134          for k in range(N+1):
     135              s = self.gen.sample(population, k)
     136              self.assertEqual(len(s), k)
     137              uniq = set(s)
     138              self.assertEqual(len(uniq), k)
     139              self.assertTrue(uniq <= set(population))
     140          self.assertEqual(self.gen.sample([], 0), [])  # test edge case N==k==0
     141          # Exception raised if size of sample exceeds that of population
     142          self.assertRaises(ValueError, self.gen.sample, population, N+1)
     143          self.assertRaises(ValueError, self.gen.sample, [], -1)
     144  
     145      def test_sample_distribution(self):
     146          # For the entire allowable range of 0 <= k <= N, validate that
     147          # sample generates all possible permutations
     148          n = 5
     149          pop = range(n)
     150          trials = 10000  # large num prevents false negatives without slowing normal case
     151          for k in range(n):
     152              expected = factorial(n) // factorial(n-k)
     153              perms = {}
     154              for i in range(trials):
     155                  perms[tuple(self.gen.sample(pop, k))] = None
     156                  if len(perms) == expected:
     157                      break
     158              else:
     159                  self.fail()
     160  
     161      def test_sample_inputs(self):
     162          # SF bug #801342 -- population can be any iterable defining __len__()
     163          self.gen.sample(range(20), 2)
     164          self.gen.sample(range(20), 2)
     165          self.gen.sample(str('abcdefghijklmnopqrst'), 2)
     166          self.gen.sample(tuple('abcdefghijklmnopqrst'), 2)
     167  
     168      def test_sample_on_dicts(self):
     169          self.assertRaises(TypeError, self.gen.sample, dict.fromkeys('abcdef'), 2)
     170  
     171      def test_sample_on_sets(self):
     172          with self.assertRaises(TypeError):
     173              population = {10, 20, 30, 40, 50, 60, 70}
     174              self.gen.sample(population, k=5)
     175  
     176      def test_sample_on_seqsets(self):
     177          class ESC[4;38;5;81mSeqSet(ESC[4;38;5;149mabcESC[4;38;5;149m.ESC[4;38;5;149mSequence, ESC[4;38;5;149mabcESC[4;38;5;149m.ESC[4;38;5;149mSet):
     178              def __init__(self, items):
     179                  self._items = items
     180  
     181              def __len__(self):
     182                  return len(self._items)
     183  
     184              def __getitem__(self, index):
     185                  return self._items[index]
     186  
     187          population = SeqSet([2, 4, 1, 3])
     188          with warnings.catch_warnings():
     189              warnings.simplefilter("error", DeprecationWarning)
     190              self.gen.sample(population, k=2)
     191  
     192      def test_sample_with_counts(self):
     193          sample = self.gen.sample
     194  
     195          # General case
     196          colors = ['red', 'green', 'blue', 'orange', 'black', 'brown', 'amber']
     197          counts = [500,      200,     20,       10,       5,       0,       1 ]
     198          k = 700
     199          summary = Counter(sample(colors, counts=counts, k=k))
     200          self.assertEqual(sum(summary.values()), k)
     201          for color, weight in zip(colors, counts):
     202              self.assertLessEqual(summary[color], weight)
     203          self.assertNotIn('brown', summary)
     204  
     205          # Case that exhausts the population
     206          k = sum(counts)
     207          summary = Counter(sample(colors, counts=counts, k=k))
     208          self.assertEqual(sum(summary.values()), k)
     209          for color, weight in zip(colors, counts):
     210              self.assertLessEqual(summary[color], weight)
     211          self.assertNotIn('brown', summary)
     212  
     213          # Case with population size of 1
     214          summary = Counter(sample(['x'], counts=[10], k=8))
     215          self.assertEqual(summary, Counter(x=8))
     216  
     217          # Case with all counts equal.
     218          nc = len(colors)
     219          summary = Counter(sample(colors, counts=[10]*nc, k=10*nc))
     220          self.assertEqual(summary, Counter(10*colors))
     221  
     222          # Test error handling
     223          with self.assertRaises(TypeError):
     224              sample(['red', 'green', 'blue'], counts=10, k=10)               # counts not iterable
     225          with self.assertRaises(ValueError):
     226              sample(['red', 'green', 'blue'], counts=[-3, -7, -8], k=2)      # counts are negative
     227          with self.assertRaises(ValueError):
     228              sample(['red', 'green', 'blue'], counts=[0, 0, 0], k=2)         # counts are zero
     229          with self.assertRaises(ValueError):
     230              sample(['red', 'green'], counts=[10, 10], k=21)                 # population too small
     231          with self.assertRaises(ValueError):
     232              sample(['red', 'green', 'blue'], counts=[1, 2], k=2)            # too few counts
     233          with self.assertRaises(ValueError):
     234              sample(['red', 'green', 'blue'], counts=[1, 2, 3, 4], k=2)      # too many counts
     235  
     236      def test_choices(self):
     237          choices = self.gen.choices
     238          data = ['red', 'green', 'blue', 'yellow']
     239          str_data = 'abcd'
     240          range_data = range(4)
     241          set_data = set(range(4))
     242  
     243          # basic functionality
     244          for sample in [
     245              choices(data, k=5),
     246              choices(data, range(4), k=5),
     247              choices(k=5, population=data, weights=range(4)),
     248              choices(k=5, population=data, cum_weights=range(4)),
     249          ]:
     250              self.assertEqual(len(sample), 5)
     251              self.assertEqual(type(sample), list)
     252              self.assertTrue(set(sample) <= set(data))
     253  
     254          # test argument handling
     255          with self.assertRaises(TypeError):                               # missing arguments
     256              choices(2)
     257  
     258          self.assertEqual(choices(data, k=0), [])                         # k == 0
     259          self.assertEqual(choices(data, k=-1), [])                        # negative k behaves like ``[0] * -1``
     260          with self.assertRaises(TypeError):
     261              choices(data, k=2.5)                                         # k is a float
     262  
     263          self.assertTrue(set(choices(str_data, k=5)) <= set(str_data))    # population is a string sequence
     264          self.assertTrue(set(choices(range_data, k=5)) <= set(range_data))  # population is a range
     265          with self.assertRaises(TypeError):
     266              choices(set_data, k=2)                                       # population is not a sequence
     267  
     268          self.assertTrue(set(choices(data, None, k=5)) <= set(data))      # weights is None
     269          self.assertTrue(set(choices(data, weights=None, k=5)) <= set(data))
     270          with self.assertRaises(ValueError):
     271              choices(data, [1,2], k=5)                                    # len(weights) != len(population)
     272          with self.assertRaises(TypeError):
     273              choices(data, 10, k=5)                                       # non-iterable weights
     274          with self.assertRaises(TypeError):
     275              choices(data, [None]*4, k=5)                                 # non-numeric weights
     276          for weights in [
     277                  [15, 10, 25, 30],                                                 # integer weights
     278                  [15.1, 10.2, 25.2, 30.3],                                         # float weights
     279                  [Fraction(1, 3), Fraction(2, 6), Fraction(3, 6), Fraction(4, 6)], # fractional weights
     280                  [True, False, True, False]                                        # booleans (include / exclude)
     281          ]:
     282              self.assertTrue(set(choices(data, weights, k=5)) <= set(data))
     283  
     284          with self.assertRaises(ValueError):
     285              choices(data, cum_weights=[1,2], k=5)                        # len(weights) != len(population)
     286          with self.assertRaises(TypeError):
     287              choices(data, cum_weights=10, k=5)                           # non-iterable cum_weights
     288          with self.assertRaises(TypeError):
     289              choices(data, cum_weights=[None]*4, k=5)                     # non-numeric cum_weights
     290          with self.assertRaises(TypeError):
     291              choices(data, range(4), cum_weights=range(4), k=5)           # both weights and cum_weights
     292          for weights in [
     293                  [15, 10, 25, 30],                                                 # integer cum_weights
     294                  [15.1, 10.2, 25.2, 30.3],                                         # float cum_weights
     295                  [Fraction(1, 3), Fraction(2, 6), Fraction(3, 6), Fraction(4, 6)], # fractional cum_weights
     296          ]:
     297              self.assertTrue(set(choices(data, cum_weights=weights, k=5)) <= set(data))
     298  
     299          # Test weight focused on a single element of the population
     300          self.assertEqual(choices('abcd', [1, 0, 0, 0]), ['a'])
     301          self.assertEqual(choices('abcd', [0, 1, 0, 0]), ['b'])
     302          self.assertEqual(choices('abcd', [0, 0, 1, 0]), ['c'])
     303          self.assertEqual(choices('abcd', [0, 0, 0, 1]), ['d'])
     304  
     305          # Test consistency with random.choice() for empty population
     306          with self.assertRaises(IndexError):
     307              choices([], k=1)
     308          with self.assertRaises(IndexError):
     309              choices([], weights=[], k=1)
     310          with self.assertRaises(IndexError):
     311              choices([], cum_weights=[], k=5)
     312  
     313      def test_choices_subnormal(self):
     314          # Subnormal weights would occasionally trigger an IndexError
     315          # in choices() when the value returned by random() was large
     316          # enough to make `random() * total` round up to the total.
     317          # See https://bugs.python.org/msg275594 for more detail.
     318          choices = self.gen.choices
     319          choices(population=[1, 2], weights=[1e-323, 1e-323], k=5000)
     320  
     321      def test_choices_with_all_zero_weights(self):
     322          # See issue #38881
     323          with self.assertRaises(ValueError):
     324              self.gen.choices('AB', [0.0, 0.0])
     325  
     326      def test_choices_negative_total(self):
     327          with self.assertRaises(ValueError):
     328              self.gen.choices('ABC', [3, -5, 1])
     329  
     330      def test_choices_infinite_total(self):
     331          with self.assertRaises(ValueError):
     332              self.gen.choices('A', [float('inf')])
     333          with self.assertRaises(ValueError):
     334              self.gen.choices('AB', [0.0, float('inf')])
     335          with self.assertRaises(ValueError):
     336              self.gen.choices('AB', [-float('inf'), 123])
     337          with self.assertRaises(ValueError):
     338              self.gen.choices('AB', [0.0, float('nan')])
     339          with self.assertRaises(ValueError):
     340              self.gen.choices('AB', [float('-inf'), float('inf')])
     341  
     342      def test_gauss(self):
     343          # Ensure that the seed() method initializes all the hidden state.  In
     344          # particular, through 2.2.1 it failed to reset a piece of state used
     345          # by (and only by) the .gauss() method.
     346  
     347          for seed in 1, 12, 123, 1234, 12345, 123456, 654321:
     348              self.gen.seed(seed)
     349              x1 = self.gen.random()
     350              y1 = self.gen.gauss(0, 1)
     351  
     352              self.gen.seed(seed)
     353              x2 = self.gen.random()
     354              y2 = self.gen.gauss(0, 1)
     355  
     356              self.assertEqual(x1, x2)
     357              self.assertEqual(y1, y2)
     358  
     359      def test_getrandbits(self):
     360          # Verify ranges
     361          for k in range(1, 1000):
     362              self.assertTrue(0 <= self.gen.getrandbits(k) < 2**k)
     363          self.assertEqual(self.gen.getrandbits(0), 0)
     364  
     365          # Verify all bits active
     366          getbits = self.gen.getrandbits
     367          for span in [1, 2, 3, 4, 31, 32, 32, 52, 53, 54, 119, 127, 128, 129]:
     368              all_bits = 2**span-1
     369              cum = 0
     370              cpl_cum = 0
     371              for i in range(100):
     372                  v = getbits(span)
     373                  cum |= v
     374                  cpl_cum |= all_bits ^ v
     375              self.assertEqual(cum, all_bits)
     376              self.assertEqual(cpl_cum, all_bits)
     377  
     378          # Verify argument checking
     379          self.assertRaises(TypeError, self.gen.getrandbits)
     380          self.assertRaises(TypeError, self.gen.getrandbits, 1, 2)
     381          self.assertRaises(ValueError, self.gen.getrandbits, -1)
     382          self.assertRaises(TypeError, self.gen.getrandbits, 10.1)
     383  
     384      def test_pickling(self):
     385          for proto in range(pickle.HIGHEST_PROTOCOL + 1):
     386              state = pickle.dumps(self.gen, proto)
     387              origseq = [self.gen.random() for i in range(10)]
     388              newgen = pickle.loads(state)
     389              restoredseq = [newgen.random() for i in range(10)]
     390              self.assertEqual(origseq, restoredseq)
     391  
     392      def test_bug_1727780(self):
     393          # verify that version-2-pickles can be loaded
     394          # fine, whether they are created on 32-bit or 64-bit
     395          # platforms, and that version-3-pickles load fine.
     396          files = [("randv2_32.pck", 780),
     397                   ("randv2_64.pck", 866),
     398                   ("randv3.pck", 343)]
     399          for file, value in files:
     400              with open(support.findfile(file),"rb") as f:
     401                  r = pickle.load(f)
     402              self.assertEqual(int(r.random()*1000), value)
     403  
     404      def test_bug_9025(self):
     405          # Had problem with an uneven distribution in int(n*random())
     406          # Verify the fix by checking that distributions fall within expectations.
     407          n = 100000
     408          randrange = self.gen.randrange
     409          k = sum(randrange(6755399441055744) % 3 == 2 for i in range(n))
     410          self.assertTrue(0.30 < k/n < .37, (k/n))
     411  
     412      def test_randbytes(self):
     413          # Verify ranges
     414          for n in range(1, 10):
     415              data = self.gen.randbytes(n)
     416              self.assertEqual(type(data), bytes)
     417              self.assertEqual(len(data), n)
     418  
     419          self.assertEqual(self.gen.randbytes(0), b'')
     420  
     421          # Verify argument checking
     422          self.assertRaises(TypeError, self.gen.randbytes)
     423          self.assertRaises(TypeError, self.gen.randbytes, 1, 2)
     424          self.assertRaises(ValueError, self.gen.randbytes, -1)
     425          self.assertRaises(TypeError, self.gen.randbytes, 1.0)
     426  
     427      def test_mu_sigma_default_args(self):
     428          self.assertIsInstance(self.gen.normalvariate(), float)
     429          self.assertIsInstance(self.gen.gauss(), float)
     430  
     431  
     432  try:
     433      random.SystemRandom().random()
     434  except NotImplementedError:
     435      SystemRandom_available = False
     436  else:
     437      SystemRandom_available = True
     438  
     439  @unittest.skipUnless(SystemRandom_available, "random.SystemRandom not available")
     440  class ESC[4;38;5;81mSystemRandom_TestBasicOps(ESC[4;38;5;149mTestBasicOps, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     441      gen = random.SystemRandom()
     442  
     443      def test_autoseed(self):
     444          # Doesn't need to do anything except not fail
     445          self.gen.seed()
     446  
     447      def test_saverestore(self):
     448          self.assertRaises(NotImplementedError, self.gen.getstate)
     449          self.assertRaises(NotImplementedError, self.gen.setstate, None)
     450  
     451      def test_seedargs(self):
     452          # Doesn't need to do anything except not fail
     453          self.gen.seed(100)
     454  
     455      def test_gauss(self):
     456          self.gen.gauss_next = None
     457          self.gen.seed(100)
     458          self.assertEqual(self.gen.gauss_next, None)
     459  
     460      def test_pickling(self):
     461          for proto in range(pickle.HIGHEST_PROTOCOL + 1):
     462              self.assertRaises(NotImplementedError, pickle.dumps, self.gen, proto)
     463  
     464      def test_53_bits_per_float(self):
     465          # This should pass whenever a C double has 53 bit precision.
     466          span = 2 ** 53
     467          cum = 0
     468          for i in range(100):
     469              cum |= int(self.gen.random() * span)
     470          self.assertEqual(cum, span-1)
     471  
     472      def test_bigrand(self):
     473          # The randrange routine should build-up the required number of bits
     474          # in stages so that all bit positions are active.
     475          span = 2 ** 500
     476          cum = 0
     477          for i in range(100):
     478              r = self.gen.randrange(span)
     479              self.assertTrue(0 <= r < span)
     480              cum |= r
     481          self.assertEqual(cum, span-1)
     482  
     483      def test_bigrand_ranges(self):
     484          for i in [40,80, 160, 200, 211, 250, 375, 512, 550]:
     485              start = self.gen.randrange(2 ** (i-2))
     486              stop = self.gen.randrange(2 ** i)
     487              if stop <= start:
     488                  continue
     489              self.assertTrue(start <= self.gen.randrange(start, stop) < stop)
     490  
     491      def test_rangelimits(self):
     492          for start, stop in [(-2,0), (-(2**60)-2,-(2**60)), (2**60,2**60+2)]:
     493              self.assertEqual(set(range(start,stop)),
     494                  set([self.gen.randrange(start,stop) for i in range(100)]))
     495  
     496      def test_randrange_nonunit_step(self):
     497          rint = self.gen.randrange(0, 10, 2)
     498          self.assertIn(rint, (0, 2, 4, 6, 8))
     499          rint = self.gen.randrange(0, 2, 2)
     500          self.assertEqual(rint, 0)
     501  
     502      def test_randrange_errors(self):
     503          raises = partial(self.assertRaises, ValueError, self.gen.randrange)
     504          # Empty range
     505          raises(3, 3)
     506          raises(-721)
     507          raises(0, 100, -12)
     508          # Non-integer start/stop
     509          self.assertWarns(DeprecationWarning, raises, 3.14159)
     510          self.assertWarns(DeprecationWarning, self.gen.randrange, 3.0)
     511          self.assertWarns(DeprecationWarning, self.gen.randrange, Fraction(3, 1))
     512          self.assertWarns(DeprecationWarning, raises, '3')
     513          self.assertWarns(DeprecationWarning, raises, 0, 2.71828)
     514          self.assertWarns(DeprecationWarning, self.gen.randrange, 0, 2.0)
     515          self.assertWarns(DeprecationWarning, self.gen.randrange, 0, Fraction(2, 1))
     516          self.assertWarns(DeprecationWarning, raises, 0, '2')
     517          # Zero and non-integer step
     518          raises(0, 42, 0)
     519          self.assertWarns(DeprecationWarning, raises, 0, 42, 0.0)
     520          self.assertWarns(DeprecationWarning, raises, 0, 0, 0.0)
     521          self.assertWarns(DeprecationWarning, raises, 0, 42, 3.14159)
     522          self.assertWarns(DeprecationWarning, self.gen.randrange, 0, 42, 3.0)
     523          self.assertWarns(DeprecationWarning, self.gen.randrange, 0, 42, Fraction(3, 1))
     524          self.assertWarns(DeprecationWarning, raises, 0, 42, '3')
     525          self.assertWarns(DeprecationWarning, self.gen.randrange, 0, 42, 1.0)
     526          self.assertWarns(DeprecationWarning, raises, 0, 0, 1.0)
     527  
     528      def test_randrange_argument_handling(self):
     529          randrange = self.gen.randrange
     530          with self.assertWarns(DeprecationWarning):
     531              randrange(10.0, 20, 2)
     532          with self.assertWarns(DeprecationWarning):
     533              randrange(10, 20.0, 2)
     534          with self.assertWarns(DeprecationWarning):
     535              randrange(10, 20, 1.0)
     536          with self.assertWarns(DeprecationWarning):
     537              randrange(10, 20, 2.0)
     538          with self.assertWarns(DeprecationWarning):
     539              with self.assertRaises(ValueError):
     540                  randrange(10.5)
     541          with self.assertWarns(DeprecationWarning):
     542              with self.assertRaises(ValueError):
     543                  randrange(10, 20.5)
     544          with self.assertWarns(DeprecationWarning):
     545              with self.assertRaises(ValueError):
     546                  randrange(10, 20, 1.5)
     547  
     548      def test_randrange_step(self):
     549          # bpo-42772: When stop is None, the step argument was being ignored.
     550          randrange = self.gen.randrange
     551          with self.assertRaises(TypeError):
     552              randrange(1000, step=100)
     553          with self.assertRaises(TypeError):
     554              randrange(1000, None, step=100)
     555  
     556      def test_randbelow_logic(self, _log=log, int=int):
     557          # check bitcount transition points:  2**i and 2**(i+1)-1
     558          # show that: k = int(1.001 + _log(n, 2))
     559          # is equal to or one greater than the number of bits in n
     560          for i in range(1, 1000):
     561              n = 1 << i # check an exact power of two
     562              numbits = i+1
     563              k = int(1.00001 + _log(n, 2))
     564              self.assertEqual(k, numbits)
     565              self.assertEqual(n, 2**(k-1))
     566  
     567              n += n - 1      # check 1 below the next power of two
     568              k = int(1.00001 + _log(n, 2))
     569              self.assertIn(k, [numbits, numbits+1])
     570              self.assertTrue(2**k > n > 2**(k-2))
     571  
     572              n -= n >> 15     # check a little farther below the next power of two
     573              k = int(1.00001 + _log(n, 2))
     574              self.assertEqual(k, numbits)        # note the stronger assertion
     575              self.assertTrue(2**k > n > 2**(k-1))   # note the stronger assertion
     576  
     577  
     578  class ESC[4;38;5;81mTestRawMersenneTwister(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     579      @test.support.cpython_only
     580      def test_bug_41052(self):
     581          # _random.Random should not be allowed to serialization
     582          import _random
     583          for proto in range(pickle.HIGHEST_PROTOCOL + 1):
     584              r = _random.Random()
     585              self.assertRaises(TypeError, pickle.dumps, r, proto)
     586  
     587      @test.support.cpython_only
     588      def test_bug_42008(self):
     589          # _random.Random should call seed with first element of arg tuple
     590          import _random
     591          r1 = _random.Random()
     592          r1.seed(8675309)
     593          r2 = _random.Random(8675309)
     594          self.assertEqual(r1.random(), r2.random())
     595  
     596  
     597  class ESC[4;38;5;81mMersenneTwister_TestBasicOps(ESC[4;38;5;149mTestBasicOps, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     598      gen = random.Random()
     599  
     600      def test_guaranteed_stable(self):
     601          # These sequences are guaranteed to stay the same across versions of python
     602          self.gen.seed(3456147, version=1)
     603          self.assertEqual([self.gen.random().hex() for i in range(4)],
     604              ['0x1.ac362300d90d2p-1', '0x1.9d16f74365005p-1',
     605               '0x1.1ebb4352e4c4dp-1', '0x1.1a7422abf9c11p-1'])
     606          self.gen.seed("the quick brown fox", version=2)
     607          self.assertEqual([self.gen.random().hex() for i in range(4)],
     608              ['0x1.1239ddfb11b7cp-3', '0x1.b3cbb5c51b120p-4',
     609               '0x1.8c4f55116b60fp-1', '0x1.63eb525174a27p-1'])
     610  
     611      def test_bug_27706(self):
     612          # Verify that version 1 seeds are unaffected by hash randomization
     613  
     614          self.gen.seed('nofar', version=1)   # hash('nofar') == 5990528763808513177
     615          self.assertEqual([self.gen.random().hex() for i in range(4)],
     616              ['0x1.8645314505ad7p-1', '0x1.afb1f82e40a40p-5',
     617               '0x1.2a59d2285e971p-1', '0x1.56977142a7880p-6'])
     618  
     619          self.gen.seed('rachel', version=1)  # hash('rachel') == -9091735575445484789
     620          self.assertEqual([self.gen.random().hex() for i in range(4)],
     621              ['0x1.0b294cc856fcdp-1', '0x1.2ad22d79e77b8p-3',
     622               '0x1.3052b9c072678p-2', '0x1.578f332106574p-3'])
     623  
     624          self.gen.seed('', version=1)        # hash('') == 0
     625          self.assertEqual([self.gen.random().hex() for i in range(4)],
     626              ['0x1.b0580f98a7dbep-1', '0x1.84129978f9c1ap-1',
     627               '0x1.aeaa51052e978p-2', '0x1.092178fb945a6p-2'])
     628  
     629      def test_bug_31478(self):
     630          # There shouldn't be an assertion failure in _random.Random.seed() in
     631          # case the argument has a bad __abs__() method.
     632          class ESC[4;38;5;81mBadInt(ESC[4;38;5;149mint):
     633              def __abs__(self):
     634                  return None
     635          try:
     636              self.gen.seed(BadInt())
     637          except TypeError:
     638              pass
     639  
     640      def test_bug_31482(self):
     641          # Verify that version 1 seeds are unaffected by hash randomization
     642          # when the seeds are expressed as bytes rather than strings.
     643          # The hash(b) values listed are the Python2.7 hash() values
     644          # which were used for seeding.
     645  
     646          self.gen.seed(b'nofar', version=1)   # hash('nofar') == 5990528763808513177
     647          self.assertEqual([self.gen.random().hex() for i in range(4)],
     648              ['0x1.8645314505ad7p-1', '0x1.afb1f82e40a40p-5',
     649               '0x1.2a59d2285e971p-1', '0x1.56977142a7880p-6'])
     650  
     651          self.gen.seed(b'rachel', version=1)  # hash('rachel') == -9091735575445484789
     652          self.assertEqual([self.gen.random().hex() for i in range(4)],
     653              ['0x1.0b294cc856fcdp-1', '0x1.2ad22d79e77b8p-3',
     654               '0x1.3052b9c072678p-2', '0x1.578f332106574p-3'])
     655  
     656          self.gen.seed(b'', version=1)        # hash('') == 0
     657          self.assertEqual([self.gen.random().hex() for i in range(4)],
     658              ['0x1.b0580f98a7dbep-1', '0x1.84129978f9c1ap-1',
     659               '0x1.aeaa51052e978p-2', '0x1.092178fb945a6p-2'])
     660  
     661          b = b'\x00\x20\x40\x60\x80\xA0\xC0\xE0\xF0'
     662          self.gen.seed(b, version=1)         # hash(b) == 5015594239749365497
     663          self.assertEqual([self.gen.random().hex() for i in range(4)],
     664              ['0x1.52c2fde444d23p-1', '0x1.875174f0daea4p-2',
     665               '0x1.9e9b2c50e5cd2p-1', '0x1.fa57768bd321cp-2'])
     666  
     667      def test_setstate_first_arg(self):
     668          self.assertRaises(ValueError, self.gen.setstate, (1, None, None))
     669  
     670      def test_setstate_middle_arg(self):
     671          start_state = self.gen.getstate()
     672          # Wrong type, s/b tuple
     673          self.assertRaises(TypeError, self.gen.setstate, (2, None, None))
     674          # Wrong length, s/b 625
     675          self.assertRaises(ValueError, self.gen.setstate, (2, (1,2,3), None))
     676          # Wrong type, s/b tuple of 625 ints
     677          self.assertRaises(TypeError, self.gen.setstate, (2, ('a',)*625, None))
     678          # Last element s/b an int also
     679          self.assertRaises(TypeError, self.gen.setstate, (2, (0,)*624+('a',), None))
     680          # Last element s/b between 0 and 624
     681          with self.assertRaises((ValueError, OverflowError)):
     682              self.gen.setstate((2, (1,)*624+(625,), None))
     683          with self.assertRaises((ValueError, OverflowError)):
     684              self.gen.setstate((2, (1,)*624+(-1,), None))
     685          # Failed calls to setstate() should not have changed the state.
     686          bits100 = self.gen.getrandbits(100)
     687          self.gen.setstate(start_state)
     688          self.assertEqual(self.gen.getrandbits(100), bits100)
     689  
     690          # Little trick to make "tuple(x % (2**32) for x in internalstate)"
     691          # raise ValueError. I cannot think of a simple way to achieve this, so
     692          # I am opting for using a generator as the middle argument of setstate
     693          # which attempts to cast a NaN to integer.
     694          state_values = self.gen.getstate()[1]
     695          state_values = list(state_values)
     696          state_values[-1] = float('nan')
     697          state = (int(x) for x in state_values)
     698          self.assertRaises(TypeError, self.gen.setstate, (2, state, None))
     699  
     700      def test_referenceImplementation(self):
     701          # Compare the python implementation with results from the original
     702          # code.  Create 2000 53-bit precision random floats.  Compare only
     703          # the last ten entries to show that the independent implementations
     704          # are tracking.  Here is the main() function needed to create the
     705          # list of expected random numbers:
     706          #    void main(void){
     707          #         int i;
     708          #         unsigned long init[4]={61731, 24903, 614, 42143}, length=4;
     709          #         init_by_array(init, length);
     710          #         for (i=0; i<2000; i++) {
     711          #           printf("%.15f ", genrand_res53());
     712          #           if (i%5==4) printf("\n");
     713          #         }
     714          #     }
     715          expected = [0.45839803073713259,
     716                      0.86057815201978782,
     717                      0.92848331726782152,
     718                      0.35932681119782461,
     719                      0.081823493762449573,
     720                      0.14332226470169329,
     721                      0.084297823823520024,
     722                      0.53814864671831453,
     723                      0.089215024911993401,
     724                      0.78486196105372907]
     725  
     726          self.gen.seed(61731 + (24903<<32) + (614<<64) + (42143<<96))
     727          actual = self.randomlist(2000)[-10:]
     728          for a, e in zip(actual, expected):
     729              self.assertAlmostEqual(a,e,places=14)
     730  
     731      def test_strong_reference_implementation(self):
     732          # Like test_referenceImplementation, but checks for exact bit-level
     733          # equality.  This should pass on any box where C double contains
     734          # at least 53 bits of precision (the underlying algorithm suffers
     735          # no rounding errors -- all results are exact).
     736          from math import ldexp
     737  
     738          expected = [0x0eab3258d2231f,
     739                      0x1b89db315277a5,
     740                      0x1db622a5518016,
     741                      0x0b7f9af0d575bf,
     742                      0x029e4c4db82240,
     743                      0x04961892f5d673,
     744                      0x02b291598e4589,
     745                      0x11388382c15694,
     746                      0x02dad977c9e1fe,
     747                      0x191d96d4d334c6]
     748          self.gen.seed(61731 + (24903<<32) + (614<<64) + (42143<<96))
     749          actual = self.randomlist(2000)[-10:]
     750          for a, e in zip(actual, expected):
     751              self.assertEqual(int(ldexp(a, 53)), e)
     752  
     753      def test_long_seed(self):
     754          # This is most interesting to run in debug mode, just to make sure
     755          # nothing blows up.  Under the covers, a dynamically resized array
     756          # is allocated, consuming space proportional to the number of bits
     757          # in the seed.  Unfortunately, that's a quadratic-time algorithm,
     758          # so don't make this horribly big.
     759          seed = (1 << (10000 * 8)) - 1  # about 10K bytes
     760          self.gen.seed(seed)
     761  
     762      def test_53_bits_per_float(self):
     763          # This should pass whenever a C double has 53 bit precision.
     764          span = 2 ** 53
     765          cum = 0
     766          for i in range(100):
     767              cum |= int(self.gen.random() * span)
     768          self.assertEqual(cum, span-1)
     769  
     770      def test_bigrand(self):
     771          # The randrange routine should build-up the required number of bits
     772          # in stages so that all bit positions are active.
     773          span = 2 ** 500
     774          cum = 0
     775          for i in range(100):
     776              r = self.gen.randrange(span)
     777              self.assertTrue(0 <= r < span)
     778              cum |= r
     779          self.assertEqual(cum, span-1)
     780  
     781      def test_bigrand_ranges(self):
     782          for i in [40,80, 160, 200, 211, 250, 375, 512, 550]:
     783              start = self.gen.randrange(2 ** (i-2))
     784              stop = self.gen.randrange(2 ** i)
     785              if stop <= start:
     786                  continue
     787              self.assertTrue(start <= self.gen.randrange(start, stop) < stop)
     788  
     789      def test_rangelimits(self):
     790          for start, stop in [(-2,0), (-(2**60)-2,-(2**60)), (2**60,2**60+2)]:
     791              self.assertEqual(set(range(start,stop)),
     792                  set([self.gen.randrange(start,stop) for i in range(100)]))
     793  
     794      def test_getrandbits(self):
     795          super().test_getrandbits()
     796  
     797          # Verify cross-platform repeatability
     798          self.gen.seed(1234567)
     799          self.assertEqual(self.gen.getrandbits(100),
     800                           97904845777343510404718956115)
     801  
     802      def test_randrange_uses_getrandbits(self):
     803          # Verify use of getrandbits by randrange
     804          # Use same seed as in the cross-platform repeatability test
     805          # in test_getrandbits above.
     806          self.gen.seed(1234567)
     807          # If randrange uses getrandbits, it should pick getrandbits(100)
     808          # when called with a 100-bits stop argument.
     809          self.assertEqual(self.gen.randrange(2**99),
     810                           97904845777343510404718956115)
     811  
     812      def test_randbelow_logic(self, _log=log, int=int):
     813          # check bitcount transition points:  2**i and 2**(i+1)-1
     814          # show that: k = int(1.001 + _log(n, 2))
     815          # is equal to or one greater than the number of bits in n
     816          for i in range(1, 1000):
     817              n = 1 << i # check an exact power of two
     818              numbits = i+1
     819              k = int(1.00001 + _log(n, 2))
     820              self.assertEqual(k, numbits)
     821              self.assertEqual(n, 2**(k-1))
     822  
     823              n += n - 1      # check 1 below the next power of two
     824              k = int(1.00001 + _log(n, 2))
     825              self.assertIn(k, [numbits, numbits+1])
     826              self.assertTrue(2**k > n > 2**(k-2))
     827  
     828              n -= n >> 15     # check a little farther below the next power of two
     829              k = int(1.00001 + _log(n, 2))
     830              self.assertEqual(k, numbits)        # note the stronger assertion
     831              self.assertTrue(2**k > n > 2**(k-1))   # note the stronger assertion
     832  
     833      def test_randbelow_without_getrandbits(self):
     834          # Random._randbelow() can only use random() when the built-in one
     835          # has been overridden but no new getrandbits() method was supplied.
     836          maxsize = 1<<random.BPF
     837          with warnings.catch_warnings():
     838              warnings.simplefilter("ignore", UserWarning)
     839              # Population range too large (n >= maxsize)
     840              self.gen._randbelow_without_getrandbits(
     841                  maxsize+1, maxsize=maxsize
     842              )
     843          self.gen._randbelow_without_getrandbits(5640, maxsize=maxsize)
     844  
     845          # This might be going too far to test a single line, but because of our
     846          # noble aim of achieving 100% test coverage we need to write a case in
     847          # which the following line in Random._randbelow() gets executed:
     848          #
     849          # rem = maxsize % n
     850          # limit = (maxsize - rem) / maxsize
     851          # r = random()
     852          # while r >= limit:
     853          #     r = random() # <== *This line* <==<
     854          #
     855          # Therefore, to guarantee that the while loop is executed at least
     856          # once, we need to mock random() so that it returns a number greater
     857          # than 'limit' the first time it gets called.
     858  
     859          n = 42
     860          epsilon = 0.01
     861          limit = (maxsize - (maxsize % n)) / maxsize
     862          with unittest.mock.patch.object(random.Random, 'random') as random_mock:
     863              random_mock.side_effect = [limit + epsilon, limit - epsilon]
     864              self.gen._randbelow_without_getrandbits(n, maxsize=maxsize)
     865              self.assertEqual(random_mock.call_count, 2)
     866  
     867      def test_randrange_bug_1590891(self):
     868          start = 1000000000000
     869          stop = -100000000000000000000
     870          step = -200
     871          x = self.gen.randrange(start, stop, step)
     872          self.assertTrue(stop < x <= start)
     873          self.assertEqual((x+stop)%step, 0)
     874  
     875      def test_choices_algorithms(self):
     876          # The various ways of specifying weights should produce the same results
     877          choices = self.gen.choices
     878          n = 104729
     879  
     880          self.gen.seed(8675309)
     881          a = self.gen.choices(range(n), k=10000)
     882  
     883          self.gen.seed(8675309)
     884          b = self.gen.choices(range(n), [1]*n, k=10000)
     885          self.assertEqual(a, b)
     886  
     887          self.gen.seed(8675309)
     888          c = self.gen.choices(range(n), cum_weights=range(1, n+1), k=10000)
     889          self.assertEqual(a, c)
     890  
     891          # American Roulette
     892          population = ['Red', 'Black', 'Green']
     893          weights = [18, 18, 2]
     894          cum_weights = [18, 36, 38]
     895          expanded_population = ['Red'] * 18 + ['Black'] * 18 + ['Green'] * 2
     896  
     897          self.gen.seed(9035768)
     898          a = self.gen.choices(expanded_population, k=10000)
     899  
     900          self.gen.seed(9035768)
     901          b = self.gen.choices(population, weights, k=10000)
     902          self.assertEqual(a, b)
     903  
     904          self.gen.seed(9035768)
     905          c = self.gen.choices(population, cum_weights=cum_weights, k=10000)
     906          self.assertEqual(a, c)
     907  
     908      def test_randbytes(self):
     909          super().test_randbytes()
     910  
     911          # Mersenne Twister randbytes() is deterministic
     912          # and does not depend on the endian and bitness.
     913          seed = 8675309
     914          expected = b'3\xa8\xf9f\xf4\xa4\xd06\x19\x8f\x9f\x82\x02oe\xf0'
     915  
     916          self.gen.seed(seed)
     917          self.assertEqual(self.gen.randbytes(16), expected)
     918  
     919          # randbytes(0) must not consume any entropy
     920          self.gen.seed(seed)
     921          self.assertEqual(self.gen.randbytes(0), b'')
     922          self.assertEqual(self.gen.randbytes(16), expected)
     923  
     924          # Four randbytes(4) calls give the same output than randbytes(16)
     925          self.gen.seed(seed)
     926          self.assertEqual(b''.join([self.gen.randbytes(4) for _ in range(4)]),
     927                           expected)
     928  
     929          # Each randbytes(1), randbytes(2) or randbytes(3) call consumes
     930          # 4 bytes of entropy
     931          self.gen.seed(seed)
     932          expected1 = expected[3::4]
     933          self.assertEqual(b''.join(self.gen.randbytes(1) for _ in range(4)),
     934                           expected1)
     935  
     936          self.gen.seed(seed)
     937          expected2 = b''.join(expected[i + 2: i + 4]
     938                               for i in range(0, len(expected), 4))
     939          self.assertEqual(b''.join(self.gen.randbytes(2) for _ in range(4)),
     940                           expected2)
     941  
     942          self.gen.seed(seed)
     943          expected3 = b''.join(expected[i + 1: i + 4]
     944                               for i in range(0, len(expected), 4))
     945          self.assertEqual(b''.join(self.gen.randbytes(3) for _ in range(4)),
     946                           expected3)
     947  
     948      def test_randbytes_getrandbits(self):
     949          # There is a simple relation between randbytes() and getrandbits()
     950          seed = 2849427419
     951          gen2 = random.Random()
     952          self.gen.seed(seed)
     953          gen2.seed(seed)
     954          for n in range(9):
     955              self.assertEqual(self.gen.randbytes(n),
     956                               gen2.getrandbits(n * 8).to_bytes(n, 'little'))
     957  
     958      def test_sample_counts_equivalence(self):
     959          # Test the documented strong equivalence to a sample with repeated elements.
     960          # We run this test on random.Random() which makes deterministic selections
     961          # for a given seed value.
     962          sample = self.gen.sample
     963          seed = self.gen.seed
     964  
     965          colors =  ['red', 'green', 'blue', 'orange', 'black', 'amber']
     966          counts = [500,      200,     20,       10,       5,       1 ]
     967          k = 700
     968          seed(8675309)
     969          s1 = sample(colors, counts=counts, k=k)
     970          seed(8675309)
     971          expanded = [color for (color, count) in zip(colors, counts) for i in range(count)]
     972          self.assertEqual(len(expanded), sum(counts))
     973          s2 = sample(expanded, k=k)
     974          self.assertEqual(s1, s2)
     975  
     976          pop = 'abcdefghi'
     977          counts = [10, 9, 8, 7, 6, 5, 4, 3, 2]
     978          seed(8675309)
     979          s1 = ''.join(sample(pop, counts=counts, k=30))
     980          expanded = ''.join([letter for (letter, count) in zip(pop, counts) for i in range(count)])
     981          seed(8675309)
     982          s2 = ''.join(sample(expanded, k=30))
     983          self.assertEqual(s1, s2)
     984  
     985  
     986  def gamma(z, sqrt2pi=(2.0*pi)**0.5):
     987      # Reflection to right half of complex plane
     988      if z < 0.5:
     989          return pi / sin(pi*z) / gamma(1.0-z)
     990      # Lanczos approximation with g=7
     991      az = z + (7.0 - 0.5)
     992      return az ** (z-0.5) / exp(az) * sqrt2pi * fsum([
     993          0.9999999999995183,
     994          676.5203681218835 / z,
     995          -1259.139216722289 / (z+1.0),
     996          771.3234287757674 / (z+2.0),
     997          -176.6150291498386 / (z+3.0),
     998          12.50734324009056 / (z+4.0),
     999          -0.1385710331296526 / (z+5.0),
    1000          0.9934937113930748e-05 / (z+6.0),
    1001          0.1659470187408462e-06 / (z+7.0),
    1002      ])
    1003  
    1004  class ESC[4;38;5;81mTestDistributions(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
    1005      def test_zeroinputs(self):
    1006          # Verify that distributions can handle a series of zero inputs'
    1007          g = random.Random()
    1008          x = [g.random() for i in range(50)] + [0.0]*5
    1009          g.random = x[:].pop; g.uniform(1,10)
    1010          g.random = x[:].pop; g.paretovariate(1.0)
    1011          g.random = x[:].pop; g.expovariate(1.0)
    1012          g.random = x[:].pop; g.weibullvariate(1.0, 1.0)
    1013          g.random = x[:].pop; g.vonmisesvariate(1.0, 1.0)
    1014          g.random = x[:].pop; g.normalvariate(0.0, 1.0)
    1015          g.random = x[:].pop; g.gauss(0.0, 1.0)
    1016          g.random = x[:].pop; g.lognormvariate(0.0, 1.0)
    1017          g.random = x[:].pop; g.vonmisesvariate(0.0, 1.0)
    1018          g.random = x[:].pop; g.gammavariate(0.01, 1.0)
    1019          g.random = x[:].pop; g.gammavariate(1.0, 1.0)
    1020          g.random = x[:].pop; g.gammavariate(200.0, 1.0)
    1021          g.random = x[:].pop; g.betavariate(3.0, 3.0)
    1022          g.random = x[:].pop; g.triangular(0.0, 1.0, 1.0/3.0)
    1023  
    1024      def test_avg_std(self):
    1025          # Use integration to test distribution average and standard deviation.
    1026          # Only works for distributions which do not consume variates in pairs
    1027          g = random.Random()
    1028          N = 5000
    1029          x = [i/float(N) for i in range(1,N)]
    1030          for variate, args, mu, sigmasqrd in [
    1031                  (g.uniform, (1.0,10.0), (10.0+1.0)/2, (10.0-1.0)**2/12),
    1032                  (g.triangular, (0.0, 1.0, 1.0/3.0), 4.0/9.0, 7.0/9.0/18.0),
    1033                  (g.expovariate, (1.5,), 1/1.5, 1/1.5**2),
    1034                  (g.vonmisesvariate, (1.23, 0), pi, pi**2/3),
    1035                  (g.paretovariate, (5.0,), 5.0/(5.0-1),
    1036                                    5.0/((5.0-1)**2*(5.0-2))),
    1037                  (g.weibullvariate, (1.0, 3.0), gamma(1+1/3.0),
    1038                                    gamma(1+2/3.0)-gamma(1+1/3.0)**2) ]:
    1039              g.random = x[:].pop
    1040              y = []
    1041              for i in range(len(x)):
    1042                  try:
    1043                      y.append(variate(*args))
    1044                  except IndexError:
    1045                      pass
    1046              s1 = s2 = 0
    1047              for e in y:
    1048                  s1 += e
    1049                  s2 += (e - mu) ** 2
    1050              N = len(y)
    1051              self.assertAlmostEqual(s1/N, mu, places=2,
    1052                                     msg='%s%r' % (variate.__name__, args))
    1053              self.assertAlmostEqual(s2/(N-1), sigmasqrd, places=2,
    1054                                     msg='%s%r' % (variate.__name__, args))
    1055  
    1056      def test_constant(self):
    1057          g = random.Random()
    1058          N = 100
    1059          for variate, args, expected in [
    1060                  (g.uniform, (10.0, 10.0), 10.0),
    1061                  (g.triangular, (10.0, 10.0), 10.0),
    1062                  (g.triangular, (10.0, 10.0, 10.0), 10.0),
    1063                  (g.expovariate, (float('inf'),), 0.0),
    1064                  (g.vonmisesvariate, (3.0, float('inf')), 3.0),
    1065                  (g.gauss, (10.0, 0.0), 10.0),
    1066                  (g.lognormvariate, (0.0, 0.0), 1.0),
    1067                  (g.lognormvariate, (-float('inf'), 0.0), 0.0),
    1068                  (g.normalvariate, (10.0, 0.0), 10.0),
    1069                  (g.paretovariate, (float('inf'),), 1.0),
    1070                  (g.weibullvariate, (10.0, float('inf')), 10.0),
    1071                  (g.weibullvariate, (0.0, 10.0), 0.0),
    1072              ]:
    1073              for i in range(N):
    1074                  self.assertEqual(variate(*args), expected)
    1075  
    1076      def test_von_mises_range(self):
    1077          # Issue 17149: von mises variates were not consistently in the
    1078          # range [0, 2*PI].
    1079          g = random.Random()
    1080          N = 100
    1081          for mu in 0.0, 0.1, 3.1, 6.2:
    1082              for kappa in 0.0, 2.3, 500.0:
    1083                  for _ in range(N):
    1084                      sample = g.vonmisesvariate(mu, kappa)
    1085                      self.assertTrue(
    1086                          0 <= sample <= random.TWOPI,
    1087                          msg=("vonmisesvariate({}, {}) produced a result {} out"
    1088                               " of range [0, 2*pi]").format(mu, kappa, sample))
    1089  
    1090      def test_von_mises_large_kappa(self):
    1091          # Issue #17141: vonmisesvariate() was hang for large kappas
    1092          random.vonmisesvariate(0, 1e15)
    1093          random.vonmisesvariate(0, 1e100)
    1094  
    1095      def test_gammavariate_errors(self):
    1096          # Both alpha and beta must be > 0.0
    1097          self.assertRaises(ValueError, random.gammavariate, -1, 3)
    1098          self.assertRaises(ValueError, random.gammavariate, 0, 2)
    1099          self.assertRaises(ValueError, random.gammavariate, 2, 0)
    1100          self.assertRaises(ValueError, random.gammavariate, 1, -3)
    1101  
    1102      # There are three different possibilities in the current implementation
    1103      # of random.gammavariate(), depending on the value of 'alpha'. What we
    1104      # are going to do here is to fix the values returned by random() to
    1105      # generate test cases that provide 100% line coverage of the method.
    1106      @unittest.mock.patch('random.Random.random')
    1107      def test_gammavariate_alpha_greater_one(self, random_mock):
    1108  
    1109          # #1: alpha > 1.0.
    1110          # We want the first random number to be outside the
    1111          # [1e-7, .9999999] range, so that the continue statement executes
    1112          # once. The values of u1 and u2 will be 0.5 and 0.3, respectively.
    1113          random_mock.side_effect = [1e-8, 0.5, 0.3]
    1114          returned_value = random.gammavariate(1.1, 2.3)
    1115          self.assertAlmostEqual(returned_value, 2.53)
    1116  
    1117      @unittest.mock.patch('random.Random.random')
    1118      def test_gammavariate_alpha_equal_one(self, random_mock):
    1119  
    1120          # #2.a: alpha == 1.
    1121          # The execution body of the while loop executes once.
    1122          # Then random.random() returns 0.45,
    1123          # which causes while to stop looping and the algorithm to terminate.
    1124          random_mock.side_effect = [0.45]
    1125          returned_value = random.gammavariate(1.0, 3.14)
    1126          self.assertAlmostEqual(returned_value, 1.877208182372648)
    1127  
    1128      @unittest.mock.patch('random.Random.random')
    1129      def test_gammavariate_alpha_equal_one_equals_expovariate(self, random_mock):
    1130  
    1131          # #2.b: alpha == 1.
    1132          # It must be equivalent of calling expovariate(1.0 / beta).
    1133          beta = 3.14
    1134          random_mock.side_effect = [1e-8, 1e-8]
    1135          gammavariate_returned_value = random.gammavariate(1.0, beta)
    1136          expovariate_returned_value = random.expovariate(1.0 / beta)
    1137          self.assertAlmostEqual(gammavariate_returned_value, expovariate_returned_value)
    1138  
    1139      @unittest.mock.patch('random.Random.random')
    1140      def test_gammavariate_alpha_between_zero_and_one(self, random_mock):
    1141  
    1142          # #3: 0 < alpha < 1.
    1143          # This is the most complex region of code to cover,
    1144          # as there are multiple if-else statements. Let's take a look at the
    1145          # source code, and determine the values that we need accordingly:
    1146          #
    1147          # while 1:
    1148          #     u = random()
    1149          #     b = (_e + alpha)/_e
    1150          #     p = b*u
    1151          #     if p <= 1.0: # <=== (A)
    1152          #         x = p ** (1.0/alpha)
    1153          #     else: # <=== (B)
    1154          #         x = -_log((b-p)/alpha)
    1155          #     u1 = random()
    1156          #     if p > 1.0: # <=== (C)
    1157          #         if u1 <= x ** (alpha - 1.0): # <=== (D)
    1158          #             break
    1159          #     elif u1 <= _exp(-x): # <=== (E)
    1160          #         break
    1161          # return x * beta
    1162          #
    1163          # First, we want (A) to be True. For that we need that:
    1164          # b*random() <= 1.0
    1165          # r1 = random() <= 1.0 / b
    1166          #
    1167          # We now get to the second if-else branch, and here, since p <= 1.0,
    1168          # (C) is False and we take the elif branch, (E). For it to be True,
    1169          # so that the break is executed, we need that:
    1170          # r2 = random() <= _exp(-x)
    1171          # r2 <= _exp(-(p ** (1.0/alpha)))
    1172          # r2 <= _exp(-((b*r1) ** (1.0/alpha)))
    1173  
    1174          _e = random._e
    1175          _exp = random._exp
    1176          _log = random._log
    1177          alpha = 0.35
    1178          beta = 1.45
    1179          b = (_e + alpha)/_e
    1180          epsilon = 0.01
    1181  
    1182          r1 = 0.8859296441566 # 1.0 / b
    1183          r2 = 0.3678794411714 # _exp(-((b*r1) ** (1.0/alpha)))
    1184  
    1185          # These four "random" values result in the following trace:
    1186          # (A) True, (E) False --> [next iteration of while]
    1187          # (A) True, (E) True --> [while loop breaks]
    1188          random_mock.side_effect = [r1, r2 + epsilon, r1, r2]
    1189          returned_value = random.gammavariate(alpha, beta)
    1190          self.assertAlmostEqual(returned_value, 1.4499999999997544)
    1191  
    1192          # Let's now make (A) be False. If this is the case, when we get to the
    1193          # second if-else 'p' is greater than 1, so (C) evaluates to True. We
    1194          # now encounter a second if statement, (D), which in order to execute
    1195          # must satisfy the following condition:
    1196          # r2 <= x ** (alpha - 1.0)
    1197          # r2 <= (-_log((b-p)/alpha)) ** (alpha - 1.0)
    1198          # r2 <= (-_log((b-(b*r1))/alpha)) ** (alpha - 1.0)
    1199          r1 = 0.8959296441566 # (1.0 / b) + epsilon -- so that (A) is False
    1200          r2 = 0.9445400408898141
    1201  
    1202          # And these four values result in the following trace:
    1203          # (B) and (C) True, (D) False --> [next iteration of while]
    1204          # (B) and (C) True, (D) True [while loop breaks]
    1205          random_mock.side_effect = [r1, r2 + epsilon, r1, r2]
    1206          returned_value = random.gammavariate(alpha, beta)
    1207          self.assertAlmostEqual(returned_value, 1.5830349561760781)
    1208  
    1209      @unittest.mock.patch('random.Random.gammavariate')
    1210      def test_betavariate_return_zero(self, gammavariate_mock):
    1211          # betavariate() returns zero when the Gamma distribution
    1212          # that it uses internally returns this same value.
    1213          gammavariate_mock.return_value = 0.0
    1214          self.assertEqual(0.0, random.betavariate(2.71828, 3.14159))
    1215  
    1216  
    1217  class ESC[4;38;5;81mTestRandomSubclassing(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
    1218      def test_random_subclass_with_kwargs(self):
    1219          # SF bug #1486663 -- this used to erroneously raise a TypeError
    1220          class ESC[4;38;5;81mSubclass(ESC[4;38;5;149mrandomESC[4;38;5;149m.ESC[4;38;5;149mRandom):
    1221              def __init__(self, newarg=None):
    1222                  random.Random.__init__(self)
    1223          Subclass(newarg=1)
    1224  
    1225      def test_subclasses_overriding_methods(self):
    1226          # Subclasses with an overridden random, but only the original
    1227          # getrandbits method should not rely on getrandbits in for randrange,
    1228          # but should use a getrandbits-independent implementation instead.
    1229  
    1230          # subclass providing its own random **and** getrandbits methods
    1231          # like random.SystemRandom does => keep relying on getrandbits for
    1232          # randrange
    1233          class ESC[4;38;5;81mSubClass1(ESC[4;38;5;149mrandomESC[4;38;5;149m.ESC[4;38;5;149mRandom):
    1234              def random(self):
    1235                  called.add('SubClass1.random')
    1236                  return random.Random.random(self)
    1237  
    1238              def getrandbits(self, n):
    1239                  called.add('SubClass1.getrandbits')
    1240                  return random.Random.getrandbits(self, n)
    1241          called = set()
    1242          SubClass1().randrange(42)
    1243          self.assertEqual(called, {'SubClass1.getrandbits'})
    1244  
    1245          # subclass providing only random => can only use random for randrange
    1246          class ESC[4;38;5;81mSubClass2(ESC[4;38;5;149mrandomESC[4;38;5;149m.ESC[4;38;5;149mRandom):
    1247              def random(self):
    1248                  called.add('SubClass2.random')
    1249                  return random.Random.random(self)
    1250          called = set()
    1251          SubClass2().randrange(42)
    1252          self.assertEqual(called, {'SubClass2.random'})
    1253  
    1254          # subclass defining getrandbits to complement its inherited random
    1255          # => can now rely on getrandbits for randrange again
    1256          class ESC[4;38;5;81mSubClass3(ESC[4;38;5;149mSubClass2):
    1257              def getrandbits(self, n):
    1258                  called.add('SubClass3.getrandbits')
    1259                  return random.Random.getrandbits(self, n)
    1260          called = set()
    1261          SubClass3().randrange(42)
    1262          self.assertEqual(called, {'SubClass3.getrandbits'})
    1263  
    1264          # subclass providing only random and inherited getrandbits
    1265          # => random takes precedence
    1266          class ESC[4;38;5;81mSubClass4(ESC[4;38;5;149mSubClass3):
    1267              def random(self):
    1268                  called.add('SubClass4.random')
    1269                  return random.Random.random(self)
    1270          called = set()
    1271          SubClass4().randrange(42)
    1272          self.assertEqual(called, {'SubClass4.random'})
    1273  
    1274          # Following subclasses don't define random or getrandbits directly,
    1275          # but inherit them from classes which are not subclasses of Random
    1276          class ESC[4;38;5;81mMixin1:
    1277              def random(self):
    1278                  called.add('Mixin1.random')
    1279                  return random.Random.random(self)
    1280          class ESC[4;38;5;81mMixin2:
    1281              def getrandbits(self, n):
    1282                  called.add('Mixin2.getrandbits')
    1283                  return random.Random.getrandbits(self, n)
    1284  
    1285          class ESC[4;38;5;81mSubClass5(ESC[4;38;5;149mMixin1, ESC[4;38;5;149mrandomESC[4;38;5;149m.ESC[4;38;5;149mRandom):
    1286              pass
    1287          called = set()
    1288          SubClass5().randrange(42)
    1289          self.assertEqual(called, {'Mixin1.random'})
    1290  
    1291          class ESC[4;38;5;81mSubClass6(ESC[4;38;5;149mMixin2, ESC[4;38;5;149mrandomESC[4;38;5;149m.ESC[4;38;5;149mRandom):
    1292              pass
    1293          called = set()
    1294          SubClass6().randrange(42)
    1295          self.assertEqual(called, {'Mixin2.getrandbits'})
    1296  
    1297          class ESC[4;38;5;81mSubClass7(ESC[4;38;5;149mMixin1, ESC[4;38;5;149mMixin2, ESC[4;38;5;149mrandomESC[4;38;5;149m.ESC[4;38;5;149mRandom):
    1298              pass
    1299          called = set()
    1300          SubClass7().randrange(42)
    1301          self.assertEqual(called, {'Mixin1.random'})
    1302  
    1303          class ESC[4;38;5;81mSubClass8(ESC[4;38;5;149mMixin2, ESC[4;38;5;149mMixin1, ESC[4;38;5;149mrandomESC[4;38;5;149m.ESC[4;38;5;149mRandom):
    1304              pass
    1305          called = set()
    1306          SubClass8().randrange(42)
    1307          self.assertEqual(called, {'Mixin2.getrandbits'})
    1308  
    1309  
    1310  class ESC[4;38;5;81mTestModule(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
    1311      def testMagicConstants(self):
    1312          self.assertAlmostEqual(random.NV_MAGICCONST, 1.71552776992141)
    1313          self.assertAlmostEqual(random.TWOPI, 6.28318530718)
    1314          self.assertAlmostEqual(random.LOG4, 1.38629436111989)
    1315          self.assertAlmostEqual(random.SG_MAGICCONST, 2.50407739677627)
    1316  
    1317      def test__all__(self):
    1318          # tests validity but not completeness of the __all__ list
    1319          self.assertTrue(set(random.__all__) <= set(dir(random)))
    1320  
    1321      @test.support.requires_fork()
    1322      def test_after_fork(self):
    1323          # Test the global Random instance gets reseeded in child
    1324          r, w = os.pipe()
    1325          pid = os.fork()
    1326          if pid == 0:
    1327              # child process
    1328              try:
    1329                  val = random.getrandbits(128)
    1330                  with open(w, "w") as f:
    1331                      f.write(str(val))
    1332              finally:
    1333                  os._exit(0)
    1334          else:
    1335              # parent process
    1336              os.close(w)
    1337              val = random.getrandbits(128)
    1338              with open(r, "r") as f:
    1339                  child_val = eval(f.read())
    1340              self.assertNotEqual(val, child_val)
    1341  
    1342              support.wait_process(pid, exitcode=0)
    1343  
    1344  
    1345  if __name__ == "__main__":
    1346      unittest.main()