Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | #!/usr/bin/env python |
2 | ||
3 | import unittest | |
4 | import random | |
5 | import time | |
6 | import pickle | |
7 | import warnings | |
8 | from math import log, exp, sqrt, pi | |
9 | from test import test_support | |
10 | ||
11 | class TestBasicOps(unittest.TestCase): | |
12 | # Superclass with tests common to all generators. | |
13 | # Subclasses must arrange for self.gen to retrieve the Random instance | |
14 | # to be tested. | |
15 | ||
16 | def randomlist(self, n): | |
17 | """Helper function to make a list of random numbers""" | |
18 | return [self.gen.random() for i in xrange(n)] | |
19 | ||
20 | def test_autoseed(self): | |
21 | self.gen.seed() | |
22 | state1 = self.gen.getstate() | |
23 | time.sleep(0.1) | |
24 | self.gen.seed() # diffent seeds at different times | |
25 | state2 = self.gen.getstate() | |
26 | self.assertNotEqual(state1, state2) | |
27 | ||
28 | def test_saverestore(self): | |
29 | N = 1000 | |
30 | self.gen.seed() | |
31 | state = self.gen.getstate() | |
32 | randseq = self.randomlist(N) | |
33 | self.gen.setstate(state) # should regenerate the same sequence | |
34 | self.assertEqual(randseq, self.randomlist(N)) | |
35 | ||
36 | def test_seedargs(self): | |
37 | for arg in [None, 0, 0L, 1, 1L, -1, -1L, 10**20, -(10**20), | |
38 | 3.14, 1+2j, 'a', tuple('abc')]: | |
39 | self.gen.seed(arg) | |
40 | for arg in [range(3), dict(one=1)]: | |
41 | self.assertRaises(TypeError, self.gen.seed, arg) | |
42 | self.assertRaises(TypeError, self.gen.seed, 1, 2) | |
43 | self.assertRaises(TypeError, type(self.gen), []) | |
44 | ||
45 | def test_jumpahead(self): | |
46 | self.gen.seed() | |
47 | state1 = self.gen.getstate() | |
48 | self.gen.jumpahead(100) | |
49 | state2 = self.gen.getstate() # s/b distinct from state1 | |
50 | self.assertNotEqual(state1, state2) | |
51 | self.gen.jumpahead(100) | |
52 | state3 = self.gen.getstate() # s/b distinct from state2 | |
53 | self.assertNotEqual(state2, state3) | |
54 | ||
55 | self.assertRaises(TypeError, self.gen.jumpahead) # needs an arg | |
56 | self.assertRaises(TypeError, self.gen.jumpahead, "ick") # wrong type | |
57 | self.assertRaises(TypeError, self.gen.jumpahead, 2.3) # wrong type | |
58 | self.assertRaises(TypeError, self.gen.jumpahead, 2, 3) # too many | |
59 | ||
60 | def test_sample(self): | |
61 | # For the entire allowable range of 0 <= k <= N, validate that | |
62 | # the sample is of the correct length and contains only unique items | |
63 | N = 100 | |
64 | population = xrange(N) | |
65 | for k in xrange(N+1): | |
66 | s = self.gen.sample(population, k) | |
67 | self.assertEqual(len(s), k) | |
68 | uniq = set(s) | |
69 | self.assertEqual(len(uniq), k) | |
70 | self.failUnless(uniq <= set(population)) | |
71 | self.assertEqual(self.gen.sample([], 0), []) # test edge case N==k==0 | |
72 | ||
73 | def test_sample_distribution(self): | |
74 | # For the entire allowable range of 0 <= k <= N, validate that | |
75 | # sample generates all possible permutations | |
76 | n = 5 | |
77 | pop = range(n) | |
78 | trials = 10000 # large num prevents false negatives without slowing normal case | |
79 | def factorial(n): | |
80 | return reduce(int.__mul__, xrange(1, n), 1) | |
81 | for k in xrange(n): | |
82 | expected = factorial(n) // factorial(n-k) | |
83 | perms = {} | |
84 | for i in xrange(trials): | |
85 | perms[tuple(self.gen.sample(pop, k))] = None | |
86 | if len(perms) == expected: | |
87 | break | |
88 | else: | |
89 | self.fail() | |
90 | ||
91 | def test_sample_inputs(self): | |
92 | # SF bug #801342 -- population can be any iterable defining __len__() | |
93 | self.gen.sample(set(range(20)), 2) | |
94 | self.gen.sample(range(20), 2) | |
95 | self.gen.sample(xrange(20), 2) | |
96 | self.gen.sample(dict.fromkeys('abcdefghijklmnopqrst'), 2) | |
97 | self.gen.sample(str('abcdefghijklmnopqrst'), 2) | |
98 | self.gen.sample(tuple('abcdefghijklmnopqrst'), 2) | |
99 | ||
100 | def test_gauss(self): | |
101 | # Ensure that the seed() method initializes all the hidden state. In | |
102 | # particular, through 2.2.1 it failed to reset a piece of state used | |
103 | # by (and only by) the .gauss() method. | |
104 | ||
105 | for seed in 1, 12, 123, 1234, 12345, 123456, 654321: | |
106 | self.gen.seed(seed) | |
107 | x1 = self.gen.random() | |
108 | y1 = self.gen.gauss(0, 1) | |
109 | ||
110 | self.gen.seed(seed) | |
111 | x2 = self.gen.random() | |
112 | y2 = self.gen.gauss(0, 1) | |
113 | ||
114 | self.assertEqual(x1, x2) | |
115 | self.assertEqual(y1, y2) | |
116 | ||
117 | def test_pickling(self): | |
118 | state = pickle.dumps(self.gen) | |
119 | origseq = [self.gen.random() for i in xrange(10)] | |
120 | newgen = pickle.loads(state) | |
121 | restoredseq = [newgen.random() for i in xrange(10)] | |
122 | self.assertEqual(origseq, restoredseq) | |
123 | ||
124 | class WichmannHill_TestBasicOps(TestBasicOps): | |
125 | gen = random.WichmannHill() | |
126 | ||
127 | def test_setstate_first_arg(self): | |
128 | self.assertRaises(ValueError, self.gen.setstate, (2, None, None)) | |
129 | ||
130 | def test_strong_jumpahead(self): | |
131 | # tests that jumpahead(n) semantics correspond to n calls to random() | |
132 | N = 1000 | |
133 | s = self.gen.getstate() | |
134 | self.gen.jumpahead(N) | |
135 | r1 = self.gen.random() | |
136 | # now do it the slow way | |
137 | self.gen.setstate(s) | |
138 | for i in xrange(N): | |
139 | self.gen.random() | |
140 | r2 = self.gen.random() | |
141 | self.assertEqual(r1, r2) | |
142 | ||
143 | def test_gauss_with_whseed(self): | |
144 | # Ensure that the seed() method initializes all the hidden state. In | |
145 | # particular, through 2.2.1 it failed to reset a piece of state used | |
146 | # by (and only by) the .gauss() method. | |
147 | ||
148 | for seed in 1, 12, 123, 1234, 12345, 123456, 654321: | |
149 | self.gen.whseed(seed) | |
150 | x1 = self.gen.random() | |
151 | y1 = self.gen.gauss(0, 1) | |
152 | ||
153 | self.gen.whseed(seed) | |
154 | x2 = self.gen.random() | |
155 | y2 = self.gen.gauss(0, 1) | |
156 | ||
157 | self.assertEqual(x1, x2) | |
158 | self.assertEqual(y1, y2) | |
159 | ||
160 | def test_bigrand(self): | |
161 | # Verify warnings are raised when randrange is too large for random() | |
162 | oldfilters = warnings.filters[:] | |
163 | warnings.filterwarnings("error", "Underlying random") | |
164 | self.assertRaises(UserWarning, self.gen.randrange, 2**60) | |
165 | warnings.filters[:] = oldfilters | |
166 | ||
167 | class SystemRandom_TestBasicOps(TestBasicOps): | |
168 | gen = random.SystemRandom() | |
169 | ||
170 | def test_autoseed(self): | |
171 | # Doesn't need to do anything except not fail | |
172 | self.gen.seed() | |
173 | ||
174 | def test_saverestore(self): | |
175 | self.assertRaises(NotImplementedError, self.gen.getstate) | |
176 | self.assertRaises(NotImplementedError, self.gen.setstate, None) | |
177 | ||
178 | def test_seedargs(self): | |
179 | # Doesn't need to do anything except not fail | |
180 | self.gen.seed(100) | |
181 | ||
182 | def test_jumpahead(self): | |
183 | # Doesn't need to do anything except not fail | |
184 | self.gen.jumpahead(100) | |
185 | ||
186 | def test_gauss(self): | |
187 | self.gen.gauss_next = None | |
188 | self.gen.seed(100) | |
189 | self.assertEqual(self.gen.gauss_next, None) | |
190 | ||
191 | def test_pickling(self): | |
192 | self.assertRaises(NotImplementedError, pickle.dumps, self.gen) | |
193 | ||
194 | def test_53_bits_per_float(self): | |
195 | # This should pass whenever a C double has 53 bit precision. | |
196 | span = 2 ** 53 | |
197 | cum = 0 | |
198 | for i in xrange(100): | |
199 | cum |= int(self.gen.random() * span) | |
200 | self.assertEqual(cum, span-1) | |
201 | ||
202 | def test_bigrand(self): | |
203 | # The randrange routine should build-up the required number of bits | |
204 | # in stages so that all bit positions are active. | |
205 | span = 2 ** 500 | |
206 | cum = 0 | |
207 | for i in xrange(100): | |
208 | r = self.gen.randrange(span) | |
209 | self.assert_(0 <= r < span) | |
210 | cum |= r | |
211 | self.assertEqual(cum, span-1) | |
212 | ||
213 | def test_bigrand_ranges(self): | |
214 | for i in [40,80, 160, 200, 211, 250, 375, 512, 550]: | |
215 | start = self.gen.randrange(2 ** i) | |
216 | stop = self.gen.randrange(2 ** (i-2)) | |
217 | if stop <= start: | |
218 | return | |
219 | self.assert_(start <= self.gen.randrange(start, stop) < stop) | |
220 | ||
221 | def test_rangelimits(self): | |
222 | for start, stop in [(-2,0), (-(2**60)-2,-(2**60)), (2**60,2**60+2)]: | |
223 | self.assertEqual(set(range(start,stop)), | |
224 | set([self.gen.randrange(start,stop) for i in xrange(100)])) | |
225 | ||
226 | def test_genrandbits(self): | |
227 | # Verify ranges | |
228 | for k in xrange(1, 1000): | |
229 | self.assert_(0 <= self.gen.getrandbits(k) < 2**k) | |
230 | ||
231 | # Verify all bits active | |
232 | getbits = self.gen.getrandbits | |
233 | for span in [1, 2, 3, 4, 31, 32, 32, 52, 53, 54, 119, 127, 128, 129]: | |
234 | cum = 0 | |
235 | for i in xrange(100): | |
236 | cum |= getbits(span) | |
237 | self.assertEqual(cum, 2**span-1) | |
238 | ||
239 | # Verify argument checking | |
240 | self.assertRaises(TypeError, self.gen.getrandbits) | |
241 | self.assertRaises(TypeError, self.gen.getrandbits, 1, 2) | |
242 | self.assertRaises(ValueError, self.gen.getrandbits, 0) | |
243 | self.assertRaises(ValueError, self.gen.getrandbits, -1) | |
244 | self.assertRaises(TypeError, self.gen.getrandbits, 10.1) | |
245 | ||
246 | def test_randbelow_logic(self, _log=log, int=int): | |
247 | # check bitcount transition points: 2**i and 2**(i+1)-1 | |
248 | # show that: k = int(1.001 + _log(n, 2)) | |
249 | # is equal to or one greater than the number of bits in n | |
250 | for i in xrange(1, 1000): | |
251 | n = 1L << i # check an exact power of two | |
252 | numbits = i+1 | |
253 | k = int(1.00001 + _log(n, 2)) | |
254 | self.assertEqual(k, numbits) | |
255 | self.assert_(n == 2**(k-1)) | |
256 | ||
257 | n += n - 1 # check 1 below the next power of two | |
258 | k = int(1.00001 + _log(n, 2)) | |
259 | self.assert_(k in [numbits, numbits+1]) | |
260 | self.assert_(2**k > n > 2**(k-2)) | |
261 | ||
262 | n -= n >> 15 # check a little farther below the next power of two | |
263 | k = int(1.00001 + _log(n, 2)) | |
264 | self.assertEqual(k, numbits) # note the stronger assertion | |
265 | self.assert_(2**k > n > 2**(k-1)) # note the stronger assertion | |
266 | ||
267 | ||
268 | class MersenneTwister_TestBasicOps(TestBasicOps): | |
269 | gen = random.Random() | |
270 | ||
271 | def test_setstate_first_arg(self): | |
272 | self.assertRaises(ValueError, self.gen.setstate, (1, None, None)) | |
273 | ||
274 | def test_setstate_middle_arg(self): | |
275 | # Wrong type, s/b tuple | |
276 | self.assertRaises(TypeError, self.gen.setstate, (2, None, None)) | |
277 | # Wrong length, s/b 625 | |
278 | self.assertRaises(ValueError, self.gen.setstate, (2, (1,2,3), None)) | |
279 | # Wrong type, s/b tuple of 625 ints | |
280 | self.assertRaises(TypeError, self.gen.setstate, (2, ('a',)*625, None)) | |
281 | # Last element s/b an int also | |
282 | self.assertRaises(TypeError, self.gen.setstate, (2, (0,)*624+('a',), None)) | |
283 | ||
284 | def test_referenceImplementation(self): | |
285 | # Compare the python implementation with results from the original | |
286 | # code. Create 2000 53-bit precision random floats. Compare only | |
287 | # the last ten entries to show that the independent implementations | |
288 | # are tracking. Here is the main() function needed to create the | |
289 | # list of expected random numbers: | |
290 | # void main(void){ | |
291 | # int i; | |
292 | # unsigned long init[4]={61731, 24903, 614, 42143}, length=4; | |
293 | # init_by_array(init, length); | |
294 | # for (i=0; i<2000; i++) { | |
295 | # printf("%.15f ", genrand_res53()); | |
296 | # if (i%5==4) printf("\n"); | |
297 | # } | |
298 | # } | |
299 | expected = [0.45839803073713259, | |
300 | 0.86057815201978782, | |
301 | 0.92848331726782152, | |
302 | 0.35932681119782461, | |
303 | 0.081823493762449573, | |
304 | 0.14332226470169329, | |
305 | 0.084297823823520024, | |
306 | 0.53814864671831453, | |
307 | 0.089215024911993401, | |
308 | 0.78486196105372907] | |
309 | ||
310 | self.gen.seed(61731L + (24903L<<32) + (614L<<64) + (42143L<<96)) | |
311 | actual = self.randomlist(2000)[-10:] | |
312 | for a, e in zip(actual, expected): | |
313 | self.assertAlmostEqual(a,e,places=14) | |
314 | ||
315 | def test_strong_reference_implementation(self): | |
316 | # Like test_referenceImplementation, but checks for exact bit-level | |
317 | # equality. This should pass on any box where C double contains | |
318 | # at least 53 bits of precision (the underlying algorithm suffers | |
319 | # no rounding errors -- all results are exact). | |
320 | from math import ldexp | |
321 | ||
322 | expected = [0x0eab3258d2231fL, | |
323 | 0x1b89db315277a5L, | |
324 | 0x1db622a5518016L, | |
325 | 0x0b7f9af0d575bfL, | |
326 | 0x029e4c4db82240L, | |
327 | 0x04961892f5d673L, | |
328 | 0x02b291598e4589L, | |
329 | 0x11388382c15694L, | |
330 | 0x02dad977c9e1feL, | |
331 | 0x191d96d4d334c6L] | |
332 | self.gen.seed(61731L + (24903L<<32) + (614L<<64) + (42143L<<96)) | |
333 | actual = self.randomlist(2000)[-10:] | |
334 | for a, e in zip(actual, expected): | |
335 | self.assertEqual(long(ldexp(a, 53)), e) | |
336 | ||
337 | def test_long_seed(self): | |
338 | # This is most interesting to run in debug mode, just to make sure | |
339 | # nothing blows up. Under the covers, a dynamically resized array | |
340 | # is allocated, consuming space proportional to the number of bits | |
341 | # in the seed. Unfortunately, that's a quadratic-time algorithm, | |
342 | # so don't make this horribly big. | |
343 | seed = (1L << (10000 * 8)) - 1 # about 10K bytes | |
344 | self.gen.seed(seed) | |
345 | ||
346 | def test_53_bits_per_float(self): | |
347 | # This should pass whenever a C double has 53 bit precision. | |
348 | span = 2 ** 53 | |
349 | cum = 0 | |
350 | for i in xrange(100): | |
351 | cum |= int(self.gen.random() * span) | |
352 | self.assertEqual(cum, span-1) | |
353 | ||
354 | def test_bigrand(self): | |
355 | # The randrange routine should build-up the required number of bits | |
356 | # in stages so that all bit positions are active. | |
357 | span = 2 ** 500 | |
358 | cum = 0 | |
359 | for i in xrange(100): | |
360 | r = self.gen.randrange(span) | |
361 | self.assert_(0 <= r < span) | |
362 | cum |= r | |
363 | self.assertEqual(cum, span-1) | |
364 | ||
365 | def test_bigrand_ranges(self): | |
366 | for i in [40,80, 160, 200, 211, 250, 375, 512, 550]: | |
367 | start = self.gen.randrange(2 ** i) | |
368 | stop = self.gen.randrange(2 ** (i-2)) | |
369 | if stop <= start: | |
370 | return | |
371 | self.assert_(start <= self.gen.randrange(start, stop) < stop) | |
372 | ||
373 | def test_rangelimits(self): | |
374 | for start, stop in [(-2,0), (-(2**60)-2,-(2**60)), (2**60,2**60+2)]: | |
375 | self.assertEqual(set(range(start,stop)), | |
376 | set([self.gen.randrange(start,stop) for i in xrange(100)])) | |
377 | ||
378 | def test_genrandbits(self): | |
379 | # Verify cross-platform repeatability | |
380 | self.gen.seed(1234567) | |
381 | self.assertEqual(self.gen.getrandbits(100), | |
382 | 97904845777343510404718956115L) | |
383 | # Verify ranges | |
384 | for k in xrange(1, 1000): | |
385 | self.assert_(0 <= self.gen.getrandbits(k) < 2**k) | |
386 | ||
387 | # Verify all bits active | |
388 | getbits = self.gen.getrandbits | |
389 | for span in [1, 2, 3, 4, 31, 32, 32, 52, 53, 54, 119, 127, 128, 129]: | |
390 | cum = 0 | |
391 | for i in xrange(100): | |
392 | cum |= getbits(span) | |
393 | self.assertEqual(cum, 2**span-1) | |
394 | ||
395 | # Verify argument checking | |
396 | self.assertRaises(TypeError, self.gen.getrandbits) | |
397 | self.assertRaises(TypeError, self.gen.getrandbits, 'a') | |
398 | self.assertRaises(TypeError, self.gen.getrandbits, 1, 2) | |
399 | self.assertRaises(ValueError, self.gen.getrandbits, 0) | |
400 | self.assertRaises(ValueError, self.gen.getrandbits, -1) | |
401 | ||
402 | def test_randbelow_logic(self, _log=log, int=int): | |
403 | # check bitcount transition points: 2**i and 2**(i+1)-1 | |
404 | # show that: k = int(1.001 + _log(n, 2)) | |
405 | # is equal to or one greater than the number of bits in n | |
406 | for i in xrange(1, 1000): | |
407 | n = 1L << i # check an exact power of two | |
408 | numbits = i+1 | |
409 | k = int(1.00001 + _log(n, 2)) | |
410 | self.assertEqual(k, numbits) | |
411 | self.assert_(n == 2**(k-1)) | |
412 | ||
413 | n += n - 1 # check 1 below the next power of two | |
414 | k = int(1.00001 + _log(n, 2)) | |
415 | self.assert_(k in [numbits, numbits+1]) | |
416 | self.assert_(2**k > n > 2**(k-2)) | |
417 | ||
418 | n -= n >> 15 # check a little farther below the next power of two | |
419 | k = int(1.00001 + _log(n, 2)) | |
420 | self.assertEqual(k, numbits) # note the stronger assertion | |
421 | self.assert_(2**k > n > 2**(k-1)) # note the stronger assertion | |
422 | ||
423 | _gammacoeff = (0.9999999999995183, 676.5203681218835, -1259.139216722289, | |
424 | 771.3234287757674, -176.6150291498386, 12.50734324009056, | |
425 | -0.1385710331296526, 0.9934937113930748e-05, 0.1659470187408462e-06) | |
426 | ||
427 | def gamma(z, cof=_gammacoeff, g=7): | |
428 | z -= 1.0 | |
429 | sum = cof[0] | |
430 | for i in xrange(1,len(cof)): | |
431 | sum += cof[i] / (z+i) | |
432 | z += 0.5 | |
433 | return (z+g)**z / exp(z+g) * sqrt(2*pi) * sum | |
434 | ||
435 | class TestDistributions(unittest.TestCase): | |
436 | def test_zeroinputs(self): | |
437 | # Verify that distributions can handle a series of zero inputs' | |
438 | g = random.Random() | |
439 | x = [g.random() for i in xrange(50)] + [0.0]*5 | |
440 | g.random = x[:].pop; g.uniform(1,10) | |
441 | g.random = x[:].pop; g.paretovariate(1.0) | |
442 | g.random = x[:].pop; g.expovariate(1.0) | |
443 | g.random = x[:].pop; g.weibullvariate(1.0, 1.0) | |
444 | g.random = x[:].pop; g.normalvariate(0.0, 1.0) | |
445 | g.random = x[:].pop; g.gauss(0.0, 1.0) | |
446 | g.random = x[:].pop; g.lognormvariate(0.0, 1.0) | |
447 | g.random = x[:].pop; g.vonmisesvariate(0.0, 1.0) | |
448 | g.random = x[:].pop; g.gammavariate(0.01, 1.0) | |
449 | g.random = x[:].pop; g.gammavariate(1.0, 1.0) | |
450 | g.random = x[:].pop; g.gammavariate(200.0, 1.0) | |
451 | g.random = x[:].pop; g.betavariate(3.0, 3.0) | |
452 | ||
453 | def test_avg_std(self): | |
454 | # Use integration to test distribution average and standard deviation. | |
455 | # Only works for distributions which do not consume variates in pairs | |
456 | g = random.Random() | |
457 | N = 5000 | |
458 | x = [i/float(N) for i in xrange(1,N)] | |
459 | for variate, args, mu, sigmasqrd in [ | |
460 | (g.uniform, (1.0,10.0), (10.0+1.0)/2, (10.0-1.0)**2/12), | |
461 | (g.expovariate, (1.5,), 1/1.5, 1/1.5**2), | |
462 | (g.paretovariate, (5.0,), 5.0/(5.0-1), | |
463 | 5.0/((5.0-1)**2*(5.0-2))), | |
464 | (g.weibullvariate, (1.0, 3.0), gamma(1+1/3.0), | |
465 | gamma(1+2/3.0)-gamma(1+1/3.0)**2) ]: | |
466 | g.random = x[:].pop | |
467 | y = [] | |
468 | for i in xrange(len(x)): | |
469 | try: | |
470 | y.append(variate(*args)) | |
471 | except IndexError: | |
472 | pass | |
473 | s1 = s2 = 0 | |
474 | for e in y: | |
475 | s1 += e | |
476 | s2 += (e - mu) ** 2 | |
477 | N = len(y) | |
478 | self.assertAlmostEqual(s1/N, mu, 2) | |
479 | self.assertAlmostEqual(s2/(N-1), sigmasqrd, 2) | |
480 | ||
481 | class TestModule(unittest.TestCase): | |
482 | def testMagicConstants(self): | |
483 | self.assertAlmostEqual(random.NV_MAGICCONST, 1.71552776992141) | |
484 | self.assertAlmostEqual(random.TWOPI, 6.28318530718) | |
485 | self.assertAlmostEqual(random.LOG4, 1.38629436111989) | |
486 | self.assertAlmostEqual(random.SG_MAGICCONST, 2.50407739677627) | |
487 | ||
488 | def test__all__(self): | |
489 | # tests validity but not completeness of the __all__ list | |
490 | self.failUnless(set(random.__all__) <= set(dir(random))) | |
491 | ||
492 | def test_main(verbose=None): | |
493 | testclasses = [WichmannHill_TestBasicOps, | |
494 | MersenneTwister_TestBasicOps, | |
495 | TestDistributions, | |
496 | TestModule] | |
497 | ||
498 | try: | |
499 | random.SystemRandom().random() | |
500 | except NotImplementedError: | |
501 | pass | |
502 | else: | |
503 | testclasses.append(SystemRandom_TestBasicOps) | |
504 | ||
505 | test_support.run_unittest(*testclasses) | |
506 | ||
507 | # verify reference counting | |
508 | import sys | |
509 | if verbose and hasattr(sys, "gettotalrefcount"): | |
510 | counts = [None] * 5 | |
511 | for i in xrange(len(counts)): | |
512 | test_support.run_unittest(*testclasses) | |
513 | counts[i] = sys.gettotalrefcount() | |
514 | print counts | |
515 | ||
516 | if __name__ == "__main__": | |
517 | test_main(verbose=True) |