• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1import unittest
2import random
3import time
4import pickle
5import warnings
6from math import log, exp, pi, fsum, sin
7from functools import reduce
8from test import test_support
9
10class TestBasicOps(unittest.TestCase):
11    # Superclass with tests common to all generators.
12    # Subclasses must arrange for self.gen to retrieve the Random instance
13    # to be tested.
14
15    def randomlist(self, n):
16        """Helper function to make a list of random numbers"""
17        return [self.gen.random() for i in xrange(n)]
18
19    def test_autoseed(self):
20        self.gen.seed()
21        state1 = self.gen.getstate()
22        time.sleep(0.1)
23        self.gen.seed()      # diffent seeds at different times
24        state2 = self.gen.getstate()
25        self.assertNotEqual(state1, state2)
26
27    def test_saverestore(self):
28        N = 1000
29        self.gen.seed()
30        state = self.gen.getstate()
31        randseq = self.randomlist(N)
32        self.gen.setstate(state)    # should regenerate the same sequence
33        self.assertEqual(randseq, self.randomlist(N))
34
35    def test_seedargs(self):
36        for arg in [None, 0, 0L, 1, 1L, -1, -1L, 10**20, -(10**20),
37                    3.14, 1+2j, 'a', tuple('abc')]:
38            self.gen.seed(arg)
39        for arg in [range(3), dict(one=1)]:
40            self.assertRaises(TypeError, self.gen.seed, arg)
41        self.assertRaises(TypeError, self.gen.seed, 1, 2)
42        self.assertRaises(TypeError, type(self.gen), [])
43
44    def test_jumpahead(self):
45        self.gen.seed()
46        state1 = self.gen.getstate()
47        self.gen.jumpahead(100)
48        state2 = self.gen.getstate()    # s/b distinct from state1
49        self.assertNotEqual(state1, state2)
50        self.gen.jumpahead(100)
51        state3 = self.gen.getstate()    # s/b distinct from state2
52        self.assertNotEqual(state2, state3)
53
54        with test_support.check_py3k_warnings(quiet=True):
55            self.assertRaises(TypeError, self.gen.jumpahead)  # needs an arg
56            self.assertRaises(TypeError, self.gen.jumpahead, 2, 3)  # too many
57
58    def test_jumpahead_produces_valid_state(self):
59        # From http://bugs.python.org/issue14591.
60        self.gen.seed(199210368)
61        self.gen.jumpahead(13550674232554645900)
62        for i in range(500):
63            val = self.gen.random()
64            self.assertLess(val, 1.0)
65
66    def test_sample(self):
67        # For the entire allowable range of 0 <= k <= N, validate that
68        # the sample is of the correct length and contains only unique items
69        N = 100
70        population = xrange(N)
71        for k in xrange(N+1):
72            s = self.gen.sample(population, k)
73            self.assertEqual(len(s), k)
74            uniq = set(s)
75            self.assertEqual(len(uniq), k)
76            self.assertTrue(uniq <= set(population))
77        self.assertEqual(self.gen.sample([], 0), [])  # test edge case N==k==0
78
79    def test_sample_distribution(self):
80        # For the entire allowable range of 0 <= k <= N, validate that
81        # sample generates all possible permutations
82        n = 5
83        pop = range(n)
84        trials = 10000  # large num prevents false negatives without slowing normal case
85        def factorial(n):
86            return reduce(int.__mul__, xrange(1, n), 1)
87        for k in xrange(n):
88            expected = factorial(n) // factorial(n-k)
89            perms = {}
90            for i in xrange(trials):
91                perms[tuple(self.gen.sample(pop, k))] = None
92                if len(perms) == expected:
93                    break
94            else:
95                self.fail()
96
97    def test_sample_inputs(self):
98        # SF bug #801342 -- population can be any iterable defining __len__()
99        self.gen.sample(set(range(20)), 2)
100        self.gen.sample(range(20), 2)
101        self.gen.sample(xrange(20), 2)
102        self.gen.sample(str('abcdefghijklmnopqrst'), 2)
103        self.gen.sample(tuple('abcdefghijklmnopqrst'), 2)
104
105    def test_sample_on_dicts(self):
106        self.gen.sample(dict.fromkeys('abcdefghijklmnopqrst'), 2)
107
108        # SF bug #1460340 -- random.sample can raise KeyError
109        a = dict.fromkeys(range(10)+range(10,100,2)+range(100,110))
110        self.gen.sample(a, 3)
111
112        # A followup to bug #1460340:  sampling from a dict could return
113        # a subset of its keys or of its values, depending on the size of
114        # the subset requested.
115        N = 30
116        d = dict((i, complex(i, i)) for i in xrange(N))
117        for k in xrange(N+1):
118            samp = self.gen.sample(d, k)
119            # Verify that we got ints back (keys); the values are complex.
120            for x in samp:
121                self.assertTrue(type(x) is int)
122        samp.sort()
123        self.assertEqual(samp, range(N))
124
125    def test_gauss(self):
126        # Ensure that the seed() method initializes all the hidden state.  In
127        # particular, through 2.2.1 it failed to reset a piece of state used
128        # by (and only by) the .gauss() method.
129
130        for seed in 1, 12, 123, 1234, 12345, 123456, 654321:
131            self.gen.seed(seed)
132            x1 = self.gen.random()
133            y1 = self.gen.gauss(0, 1)
134
135            self.gen.seed(seed)
136            x2 = self.gen.random()
137            y2 = self.gen.gauss(0, 1)
138
139            self.assertEqual(x1, x2)
140            self.assertEqual(y1, y2)
141
142    def test_pickling(self):
143        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
144            state = pickle.dumps(self.gen, proto)
145            origseq = [self.gen.random() for i in xrange(10)]
146            newgen = pickle.loads(state)
147            restoredseq = [newgen.random() for i in xrange(10)]
148            self.assertEqual(origseq, restoredseq)
149
150    def test_bug_1727780(self):
151        # verify that version-2-pickles can be loaded
152        # fine, whether they are created on 32-bit or 64-bit
153        # platforms, and that version-3-pickles load fine.
154        files = [("randv2_32.pck", 780),
155                 ("randv2_64.pck", 866),
156                 ("randv3.pck", 343)]
157        for file, value in files:
158            f = open(test_support.findfile(file),"rb")
159            r = pickle.load(f)
160            f.close()
161            self.assertEqual(r.randrange(1000), value)
162
163class WichmannHill_TestBasicOps(TestBasicOps):
164    gen = random.WichmannHill()
165
166    def test_setstate_first_arg(self):
167        self.assertRaises(ValueError, self.gen.setstate, (2, None, None))
168
169    def test_strong_jumpahead(self):
170        # tests that jumpahead(n) semantics correspond to n calls to random()
171        N = 1000
172        s = self.gen.getstate()
173        self.gen.jumpahead(N)
174        r1 = self.gen.random()
175        # now do it the slow way
176        self.gen.setstate(s)
177        for i in xrange(N):
178            self.gen.random()
179        r2 = self.gen.random()
180        self.assertEqual(r1, r2)
181
182    def test_gauss_with_whseed(self):
183        # Ensure that the seed() method initializes all the hidden state.  In
184        # particular, through 2.2.1 it failed to reset a piece of state used
185        # by (and only by) the .gauss() method.
186
187        for seed in 1, 12, 123, 1234, 12345, 123456, 654321:
188            self.gen.whseed(seed)
189            x1 = self.gen.random()
190            y1 = self.gen.gauss(0, 1)
191
192            self.gen.whseed(seed)
193            x2 = self.gen.random()
194            y2 = self.gen.gauss(0, 1)
195
196            self.assertEqual(x1, x2)
197            self.assertEqual(y1, y2)
198
199    def test_bigrand(self):
200        # Verify warnings are raised when randrange is too large for random()
201        with warnings.catch_warnings():
202            warnings.filterwarnings("error", "Underlying random")
203            self.assertRaises(UserWarning, self.gen.randrange, 2**60)
204
205class SystemRandom_TestBasicOps(TestBasicOps):
206    gen = random.SystemRandom()
207
208    def test_autoseed(self):
209        # Doesn't need to do anything except not fail
210        self.gen.seed()
211
212    def test_saverestore(self):
213        self.assertRaises(NotImplementedError, self.gen.getstate)
214        self.assertRaises(NotImplementedError, self.gen.setstate, None)
215
216    def test_seedargs(self):
217        # Doesn't need to do anything except not fail
218        self.gen.seed(100)
219
220    def test_jumpahead(self):
221        # Doesn't need to do anything except not fail
222        self.gen.jumpahead(100)
223
224    def test_gauss(self):
225        self.gen.gauss_next = None
226        self.gen.seed(100)
227        self.assertEqual(self.gen.gauss_next, None)
228
229    def test_pickling(self):
230        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
231            self.assertRaises(NotImplementedError, pickle.dumps, self.gen, proto)
232
233    def test_53_bits_per_float(self):
234        # This should pass whenever a C double has 53 bit precision.
235        span = 2 ** 53
236        cum = 0
237        for i in xrange(100):
238            cum |= int(self.gen.random() * span)
239        self.assertEqual(cum, span-1)
240
241    def test_bigrand(self):
242        # The randrange routine should build-up the required number of bits
243        # in stages so that all bit positions are active.
244        span = 2 ** 500
245        cum = 0
246        for i in xrange(100):
247            r = self.gen.randrange(span)
248            self.assertTrue(0 <= r < span)
249            cum |= r
250        self.assertEqual(cum, span-1)
251
252    def test_bigrand_ranges(self):
253        for i in [40,80, 160, 200, 211, 250, 375, 512, 550]:
254            start = self.gen.randrange(2 ** (i-2))
255            stop = self.gen.randrange(2 ** i)
256            if stop <= start:
257                continue
258            self.assertTrue(start <= self.gen.randrange(start, stop) < stop)
259
260    def test_rangelimits(self):
261        for start, stop in [(-2,0), (-(2**60)-2,-(2**60)), (2**60,2**60+2)]:
262            self.assertEqual(set(range(start,stop)),
263                set([self.gen.randrange(start,stop) for i in xrange(100)]))
264
265    def test_genrandbits(self):
266        # Verify ranges
267        for k in xrange(1, 1000):
268            self.assertTrue(0 <= self.gen.getrandbits(k) < 2**k)
269
270        # Verify all bits active
271        getbits = self.gen.getrandbits
272        for span in [1, 2, 3, 4, 31, 32, 32, 52, 53, 54, 119, 127, 128, 129]:
273            cum = 0
274            for i in xrange(100):
275                cum |= getbits(span)
276            self.assertEqual(cum, 2**span-1)
277
278        # Verify argument checking
279        self.assertRaises(TypeError, self.gen.getrandbits)
280        self.assertRaises(TypeError, self.gen.getrandbits, 1, 2)
281        self.assertRaises(ValueError, self.gen.getrandbits, 0)
282        self.assertRaises(ValueError, self.gen.getrandbits, -1)
283        self.assertRaises(TypeError, self.gen.getrandbits, 10.1)
284
285    def test_randbelow_logic(self, _log=log, int=int):
286        # check bitcount transition points:  2**i and 2**(i+1)-1
287        # show that: k = int(1.001 + _log(n, 2))
288        # is equal to or one greater than the number of bits in n
289        for i in xrange(1, 1000):
290            n = 1L << i # check an exact power of two
291            numbits = i+1
292            k = int(1.00001 + _log(n, 2))
293            self.assertEqual(k, numbits)
294            self.assertTrue(n == 2**(k-1))
295
296            n += n - 1      # check 1 below the next power of two
297            k = int(1.00001 + _log(n, 2))
298            self.assertIn(k, [numbits, numbits+1])
299            self.assertTrue(2**k > n > 2**(k-2))
300
301            n -= n >> 15     # check a little farther below the next power of two
302            k = int(1.00001 + _log(n, 2))
303            self.assertEqual(k, numbits)        # note the stronger assertion
304            self.assertTrue(2**k > n > 2**(k-1))   # note the stronger assertion
305
306
307class MersenneTwister_TestBasicOps(TestBasicOps):
308    gen = random.Random()
309
310    @test_support.cpython_only
311    def test_bug_31478(self):
312        # _random.Random.seed() should ignore the __abs__() method of a
313        # long/int subclass argument.
314        class BadInt(int):
315            def __abs__(self):
316                1/0.0
317        class BadLong(long):
318            def __abs__(self):
319                1/0.0
320        self.gen.seed(42)
321        expected_value = self.gen.random()
322        for seed_arg in [42L, BadInt(42), BadLong(42)]:
323            self.gen.seed(seed_arg)
324            self.assertEqual(self.gen.random(), expected_value)
325
326    def test_setstate_first_arg(self):
327        self.assertRaises(ValueError, self.gen.setstate, (1, None, None))
328
329    def test_setstate_middle_arg(self):
330        start_state = self.gen.getstate()
331        # Wrong type, s/b tuple
332        self.assertRaises(TypeError, self.gen.setstate, (2, None, None))
333        # Wrong length, s/b 625
334        self.assertRaises(ValueError, self.gen.setstate, (2, (1,2,3), None))
335        # Wrong type, s/b tuple of 625 ints
336        self.assertRaises(TypeError, self.gen.setstate, (2, ('a',)*625, None))
337        # Last element s/b an int also
338        self.assertRaises(TypeError, self.gen.setstate, (2, (0,)*624+('a',), None))
339        # Last element s/b between 0 and 624
340        with self.assertRaises((ValueError, OverflowError)):
341            self.gen.setstate((2, (1,)*624+(625,), None))
342        with self.assertRaises((ValueError, OverflowError)):
343            self.gen.setstate((2, (1,)*624+(-1,), None))
344        # Failed calls to setstate() should not have changed the state.
345        bits100 = self.gen.getrandbits(100)
346        self.gen.setstate(start_state)
347        self.assertEqual(self.gen.getrandbits(100), bits100)
348
349    def test_referenceImplementation(self):
350        # Compare the python implementation with results from the original
351        # code.  Create 2000 53-bit precision random floats.  Compare only
352        # the last ten entries to show that the independent implementations
353        # are tracking.  Here is the main() function needed to create the
354        # list of expected random numbers:
355        #    void main(void){
356        #         int i;
357        #         unsigned long init[4]={61731, 24903, 614, 42143}, length=4;
358        #         init_by_array(init, length);
359        #         for (i=0; i<2000; i++) {
360        #           printf("%.15f ", genrand_res53());
361        #           if (i%5==4) printf("\n");
362        #         }
363        #     }
364        expected = [0.45839803073713259,
365                    0.86057815201978782,
366                    0.92848331726782152,
367                    0.35932681119782461,
368                    0.081823493762449573,
369                    0.14332226470169329,
370                    0.084297823823520024,
371                    0.53814864671831453,
372                    0.089215024911993401,
373                    0.78486196105372907]
374
375        self.gen.seed(61731L + (24903L<<32) + (614L<<64) + (42143L<<96))
376        actual = self.randomlist(2000)[-10:]
377        for a, e in zip(actual, expected):
378            self.assertAlmostEqual(a,e,places=14)
379
380    def test_strong_reference_implementation(self):
381        # Like test_referenceImplementation, but checks for exact bit-level
382        # equality.  This should pass on any box where C double contains
383        # at least 53 bits of precision (the underlying algorithm suffers
384        # no rounding errors -- all results are exact).
385        from math import ldexp
386
387        expected = [0x0eab3258d2231fL,
388                    0x1b89db315277a5L,
389                    0x1db622a5518016L,
390                    0x0b7f9af0d575bfL,
391                    0x029e4c4db82240L,
392                    0x04961892f5d673L,
393                    0x02b291598e4589L,
394                    0x11388382c15694L,
395                    0x02dad977c9e1feL,
396                    0x191d96d4d334c6L]
397        self.gen.seed(61731L + (24903L<<32) + (614L<<64) + (42143L<<96))
398        actual = self.randomlist(2000)[-10:]
399        for a, e in zip(actual, expected):
400            self.assertEqual(long(ldexp(a, 53)), e)
401
402    def test_long_seed(self):
403        # This is most interesting to run in debug mode, just to make sure
404        # nothing blows up.  Under the covers, a dynamically resized array
405        # is allocated, consuming space proportional to the number of bits
406        # in the seed.  Unfortunately, that's a quadratic-time algorithm,
407        # so don't make this horribly big.
408        seed = (1L << (10000 * 8)) - 1  # about 10K bytes
409        self.gen.seed(seed)
410
411    def test_53_bits_per_float(self):
412        # This should pass whenever a C double has 53 bit precision.
413        span = 2 ** 53
414        cum = 0
415        for i in xrange(100):
416            cum |= int(self.gen.random() * span)
417        self.assertEqual(cum, span-1)
418
419    def test_bigrand(self):
420        # The randrange routine should build-up the required number of bits
421        # in stages so that all bit positions are active.
422        span = 2 ** 500
423        cum = 0
424        for i in xrange(100):
425            r = self.gen.randrange(span)
426            self.assertTrue(0 <= r < span)
427            cum |= r
428        self.assertEqual(cum, span-1)
429
430    def test_bigrand_ranges(self):
431        for i in [40,80, 160, 200, 211, 250, 375, 512, 550]:
432            start = self.gen.randrange(2 ** (i-2))
433            stop = self.gen.randrange(2 ** i)
434            if stop <= start:
435                continue
436            self.assertTrue(start <= self.gen.randrange(start, stop) < stop)
437
438    def test_rangelimits(self):
439        for start, stop in [(-2,0), (-(2**60)-2,-(2**60)), (2**60,2**60+2)]:
440            self.assertEqual(set(range(start,stop)),
441                set([self.gen.randrange(start,stop) for i in xrange(100)]))
442
443    def test_genrandbits(self):
444        # Verify cross-platform repeatability
445        self.gen.seed(1234567)
446        self.assertEqual(self.gen.getrandbits(100),
447                         97904845777343510404718956115L)
448        # Verify ranges
449        for k in xrange(1, 1000):
450            self.assertTrue(0 <= self.gen.getrandbits(k) < 2**k)
451
452        # Verify all bits active
453        getbits = self.gen.getrandbits
454        for span in [1, 2, 3, 4, 31, 32, 32, 52, 53, 54, 119, 127, 128, 129]:
455            cum = 0
456            for i in xrange(100):
457                cum |= getbits(span)
458            self.assertEqual(cum, 2**span-1)
459
460        # Verify argument checking
461        self.assertRaises(TypeError, self.gen.getrandbits)
462        self.assertRaises(TypeError, self.gen.getrandbits, 'a')
463        self.assertRaises(TypeError, self.gen.getrandbits, 1, 2)
464        self.assertRaises(ValueError, self.gen.getrandbits, 0)
465        self.assertRaises(ValueError, self.gen.getrandbits, -1)
466
467    def test_randbelow_logic(self, _log=log, int=int):
468        # check bitcount transition points:  2**i and 2**(i+1)-1
469        # show that: k = int(1.001 + _log(n, 2))
470        # is equal to or one greater than the number of bits in n
471        for i in xrange(1, 1000):
472            n = 1L << i # check an exact power of two
473            numbits = i+1
474            k = int(1.00001 + _log(n, 2))
475            self.assertEqual(k, numbits)
476            self.assertTrue(n == 2**(k-1))
477
478            n += n - 1      # check 1 below the next power of two
479            k = int(1.00001 + _log(n, 2))
480            self.assertIn(k, [numbits, numbits+1])
481            self.assertTrue(2**k > n > 2**(k-2))
482
483            n -= n >> 15     # check a little farther below the next power of two
484            k = int(1.00001 + _log(n, 2))
485            self.assertEqual(k, numbits)        # note the stronger assertion
486            self.assertTrue(2**k > n > 2**(k-1))   # note the stronger assertion
487
488    def test_randrange_bug_1590891(self):
489        start = 1000000000000
490        stop = -100000000000000000000
491        step = -200
492        x = self.gen.randrange(start, stop, step)
493        self.assertTrue(stop < x <= start)
494        self.assertEqual((x+stop)%step, 0)
495
496def gamma(z, sqrt2pi=(2.0*pi)**0.5):
497    # Reflection to right half of complex plane
498    if z < 0.5:
499        return pi / sin(pi*z) / gamma(1.0-z)
500    # Lanczos approximation with g=7
501    az = z + (7.0 - 0.5)
502    return az ** (z-0.5) / exp(az) * sqrt2pi * fsum([
503        0.9999999999995183,
504        676.5203681218835 / z,
505        -1259.139216722289 / (z+1.0),
506        771.3234287757674 / (z+2.0),
507        -176.6150291498386 / (z+3.0),
508        12.50734324009056 / (z+4.0),
509        -0.1385710331296526 / (z+5.0),
510        0.9934937113930748e-05 / (z+6.0),
511        0.1659470187408462e-06 / (z+7.0),
512    ])
513
514class TestDistributions(unittest.TestCase):
515    def test_zeroinputs(self):
516        # Verify that distributions can handle a series of zero inputs'
517        g = random.Random()
518        x = [g.random() for i in xrange(50)] + [0.0]*5
519        g.random = x[:].pop; g.uniform(1,10)
520        g.random = x[:].pop; g.paretovariate(1.0)
521        g.random = x[:].pop; g.expovariate(1.0)
522        g.random = x[:].pop; g.weibullvariate(1.0, 1.0)
523        g.random = x[:].pop; g.vonmisesvariate(1.0, 1.0)
524        g.random = x[:].pop; g.normalvariate(0.0, 1.0)
525        g.random = x[:].pop; g.gauss(0.0, 1.0)
526        g.random = x[:].pop; g.lognormvariate(0.0, 1.0)
527        g.random = x[:].pop; g.vonmisesvariate(0.0, 1.0)
528        g.random = x[:].pop; g.gammavariate(0.01, 1.0)
529        g.random = x[:].pop; g.gammavariate(1.0, 1.0)
530        g.random = x[:].pop; g.gammavariate(200.0, 1.0)
531        g.random = x[:].pop; g.betavariate(3.0, 3.0)
532        g.random = x[:].pop; g.triangular(0.0, 1.0, 1.0/3.0)
533
534    def test_avg_std(self):
535        # Use integration to test distribution average and standard deviation.
536        # Only works for distributions which do not consume variates in pairs
537        g = random.Random()
538        N = 5000
539        x = [i/float(N) for i in xrange(1,N)]
540        for variate, args, mu, sigmasqrd in [
541                (g.uniform, (1.0,10.0), (10.0+1.0)/2, (10.0-1.0)**2/12),
542                (g.triangular, (0.0, 1.0, 1.0/3.0), 4.0/9.0, 7.0/9.0/18.0),
543                (g.expovariate, (1.5,), 1/1.5, 1/1.5**2),
544                (g.vonmisesvariate, (1.23, 0), pi, pi**2/3),
545                (g.paretovariate, (5.0,), 5.0/(5.0-1),
546                                  5.0/((5.0-1)**2*(5.0-2))),
547                (g.weibullvariate, (1.0, 3.0), gamma(1+1/3.0),
548                                  gamma(1+2/3.0)-gamma(1+1/3.0)**2) ]:
549            g.random = x[:].pop
550            y = []
551            for i in xrange(len(x)):
552                try:
553                    y.append(variate(*args))
554                except IndexError:
555                    pass
556            s1 = s2 = 0
557            for e in y:
558                s1 += e
559                s2 += (e - mu) ** 2
560            N = len(y)
561            self.assertAlmostEqual(s1/N, mu, places=2,
562                                   msg='%s%r' % (variate.__name__, args))
563            self.assertAlmostEqual(s2/(N-1), sigmasqrd, places=2,
564                                   msg='%s%r' % (variate.__name__, args))
565
566    def test_constant(self):
567        g = random.Random()
568        N = 100
569        for variate, args, expected in [
570                (g.uniform, (10.0, 10.0), 10.0),
571                (g.triangular, (10.0, 10.0), 10.0),
572                (g.triangular, (10.0, 10.0, 10.0), 10.0),
573                (g.expovariate, (float('inf'),), 0.0),
574                (g.vonmisesvariate, (3.0, float('inf')), 3.0),
575                (g.gauss, (10.0, 0.0), 10.0),
576                (g.lognormvariate, (0.0, 0.0), 1.0),
577                (g.lognormvariate, (-float('inf'), 0.0), 0.0),
578                (g.normalvariate, (10.0, 0.0), 10.0),
579                (g.paretovariate, (float('inf'),), 1.0),
580                (g.weibullvariate, (10.0, float('inf')), 10.0),
581                (g.weibullvariate, (0.0, 10.0), 0.0),
582            ]:
583            for i in range(N):
584                self.assertEqual(variate(*args), expected)
585
586    def test_von_mises_range(self):
587        # Issue 17149: von mises variates were not consistently in the
588        # range [0, 2*PI].
589        g = random.Random()
590        N = 100
591        for mu in 0.0, 0.1, 3.1, 6.2:
592            for kappa in 0.0, 2.3, 500.0:
593                for _ in range(N):
594                    sample = g.vonmisesvariate(mu, kappa)
595                    self.assertTrue(
596                        0 <= sample <= random.TWOPI,
597                        msg=("vonmisesvariate({}, {}) produced a result {} out"
598                             " of range [0, 2*pi]").format(mu, kappa, sample))
599
600    def test_von_mises_large_kappa(self):
601        # Issue #17141: vonmisesvariate() was hang for large kappas
602        random.vonmisesvariate(0, 1e15)
603        random.vonmisesvariate(0, 1e100)
604
605
606class TestModule(unittest.TestCase):
607    def testMagicConstants(self):
608        self.assertAlmostEqual(random.NV_MAGICCONST, 1.71552776992141)
609        self.assertAlmostEqual(random.TWOPI, 6.28318530718)
610        self.assertAlmostEqual(random.LOG4, 1.38629436111989)
611        self.assertAlmostEqual(random.SG_MAGICCONST, 2.50407739677627)
612
613    def test__all__(self):
614        # tests validity but not completeness of the __all__ list
615        self.assertTrue(set(random.__all__) <= set(dir(random)))
616
617    def test_random_subclass_with_kwargs(self):
618        # SF bug #1486663 -- this used to erroneously raise a TypeError
619        class Subclass(random.Random):
620            def __init__(self, newarg=None):
621                random.Random.__init__(self)
622        Subclass(newarg=1)
623
624
625def test_main(verbose=None):
626    testclasses =    [WichmannHill_TestBasicOps,
627                      MersenneTwister_TestBasicOps,
628                      TestDistributions,
629                      TestModule]
630
631    try:
632        random.SystemRandom().random()
633    except NotImplementedError:
634        pass
635    else:
636        testclasses.append(SystemRandom_TestBasicOps)
637
638    test_support.run_unittest(*testclasses)
639
640    # verify reference counting
641    import sys
642    if verbose and hasattr(sys, "gettotalrefcount"):
643        counts = [None] * 5
644        for i in xrange(len(counts)):
645            test_support.run_unittest(*testclasses)
646            counts[i] = sys.gettotalrefcount()
647        print counts
648
649if __name__ == "__main__":
650    test_main(verbose=True)
651