11from decimal import Decimal
22from fractions import Fraction
3+ import itertools
4+ import random
35import unittest
46from test import support
57
@@ -78,6 +80,47 @@ def py_factorial(n):
7880 outer *= inner
7981 return outer << (n - count_set_bits (n ))
8082
83+ # Reference implementations for primality testing.
84+
85+ def primes_below (n ):
86+ """List of the primes below n, by the sieve of Eratosthenes."""
87+ sieve = bytearray ([1 ]) * n
88+ sieve [:2 ] = bytes (2 )
89+ i = 2
90+ while i * i < n :
91+ if sieve [i ]:
92+ sieve [i * i ::i ] = bytes (len (range (i * i , n , i )))
93+ i += 1
94+ return [i for i in range (n ) if sieve [i ]]
95+
96+ # The Miller-Rabin test with the first 13 primes as bases is known to be
97+ # exact for n < 3.3 * 10**24. More bases are used for larger inputs, for
98+ # which the test is probabilistic (but independent of the Baillie-PSW test
99+ # used in the implementation).
100+ MILLER_RABIN_BASES = primes_below (100 )
101+
102+ def py_isprime (n ):
103+ """Miller-Rabin primality test, for cross-checking."""
104+ if n < 2 :
105+ return False
106+ for p in MILLER_RABIN_BASES :
107+ if n % p == 0 :
108+ return n == p
109+ d = n - 1
110+ s = (d & - d ).bit_length () - 1
111+ d >>= s
112+ for a in MILLER_RABIN_BASES :
113+ x = pow (a , d , n )
114+ if x == 1 or x == n - 1 :
115+ continue
116+ for _ in range (s - 1 ):
117+ x = x * x % n
118+ if x == n - 1 :
119+ break
120+ else :
121+ return False
122+ return True
123+
81124
82125class IntMathTests (unittest .TestCase ):
83126 import math .integer as module
@@ -406,6 +449,246 @@ class MathTests(IntMathTests):
406449 import math as module
407450
408451
452+ # isprime() and primes() exist only in math.integer, not in math, so their
453+ # tests are not in IntMathTests (which is re-run against math above).
454+
455+ class IsPrimeTests (unittest .TestCase ):
456+ import math .integer as module
457+
458+ def test_isprime_small (self ):
459+ isprime = self .module .isprime
460+ sieve = set (primes_below (10 ** 4 ))
461+ for n in range (- 10 , 10 ** 4 ):
462+ with self .subTest (n = n ):
463+ self .assertIs (isprime (n ), n in sieve )
464+
465+ def test_isprime_negative (self ):
466+ isprime = self .module .isprime
467+ self .assertIs (isprime (- 1 ), False )
468+ self .assertIs (isprime (- 2 ), False )
469+ self .assertIs (isprime (- 3 ), False )
470+ self .assertIs (isprime (- 10 ** 100 ), False )
471+
472+ def test_isprime_carmichael (self ):
473+ # Carmichael numbers are composite (A002997).
474+ isprime = self .module .isprime
475+ for n in [561 , 1105 , 1729 , 2465 , 2821 , 6601 , 8911 , 10585 , 15841 ,
476+ 29341 , 41041 , 46657 , 52633 , 62745 , 63973 , 75361 ]:
477+ with self .subTest (n = n ):
478+ self .assertIs (isprime (n ), False )
479+
480+ def test_isprime_strong_pseudoprimes_base_2 (self ):
481+ # Composites that pass the strong probable prime test to base 2
482+ # (A001262); they must be caught by the strong Lucas test.
483+ isprime = self .module .isprime
484+ for n in [2047 , 3277 , 4033 , 4681 , 8321 , 15841 , 29341 , 42799 , 49141 ,
485+ 52633 , 65281 , 74665 , 80581 , 85489 , 88357 , 90751 ,
486+ 3825123056546413051 ]:
487+ with self .subTest (n = n ):
488+ self .assertIs (isprime (n ), False )
489+
490+ def test_isprime_strong_lucas_pseudoprimes (self ):
491+ # Composites that pass the strong Lucas test with Selfridge's
492+ # parameters (A217255).
493+ isprime = self .module .isprime
494+ for n in [5459 , 5777 , 10877 , 16109 , 18971 , 22499 , 24569 , 25199 ,
495+ 40309 , 58519 , 75077 , 97439 ]:
496+ with self .subTest (n = n ):
497+ self .assertIs (isprime (n ), False )
498+
499+ def test_isprime_base_divisors (self ):
500+ # Divisors of the Miller-Rabin bases exercise the case where a
501+ # base is divisible by the tested number.
502+ isprime = self .module .isprime
503+ for base in [2 , 7 , 61 , 325 , 9375 , 28178 , 450775 , 9780504 ,
504+ 1795265022 ]:
505+ d = 1
506+ while d * d <= base :
507+ if base % d == 0 :
508+ for n in [d , base // d ]:
509+ with self .subTest (base = base , n = n ):
510+ self .assertIs (isprime (n ), py_isprime (n ))
511+ d += 1
512+
513+ def test_isprime_perfect_squares (self ):
514+ isprime = self .module .isprime
515+ for k in range (1000 ):
516+ with self .subTest (k = k ):
517+ self .assertIs (isprime (k * k ), False )
518+ for k in [2 ** 31 - 1 , 2 ** 32 - 5 ]:
519+ with self .subTest (k = k ):
520+ self .assertIs (isprime (k * k ), False )
521+
522+ def test_isprime_word_boundaries (self ):
523+ # Exercise the boundaries between the base sets.
524+ isprime = self .module .isprime
525+ for boundary in [2 ** 32 , 4759123141 ]:
526+ for n in range (boundary - 200 , boundary + 200 ):
527+ with self .subTest (n = n ):
528+ self .assertIs (isprime (n ), py_isprime (n ))
529+ for n in range (2 ** 64 - 200 , 2 ** 64 ):
530+ with self .subTest (n = n ):
531+ self .assertIs (isprime (n ), py_isprime (n ))
532+ self .assertIs (isprime (2 ** 64 - 59 ), True ) # largest prime < 2**64
533+
534+ def test_isprime_large_values (self ):
535+ isprime = self .module .isprime
536+ self .assertIs (isprime (2 ** 61 - 1 ), True ) # Mersenne prime
537+ self .assertIs (isprime (2 ** 62 - 1 ), False )
538+ self .assertIs (isprime (10 ** 19 ), False )
539+ # Arguments not less than 2**64 are not supported.
540+ for n in [2 ** 64 , 2 ** 64 + 13 , 2 ** 89 - 1 , 10 ** 100 ]:
541+ with self .subTest (n = n ):
542+ self .assertRaises (OverflowError , isprime , n )
543+
544+ def test_isprime_random (self ):
545+ isprime = self .module .isprime
546+ rng = random .Random (1729 )
547+ for bits in [32 , 34 , 63 , 64 ]:
548+ for _ in range (300 ):
549+ n = rng .getrandbits (bits )
550+ with self .subTest (n = n ):
551+ self .assertIs (isprime (n ), py_isprime (n ))
552+ for bits in [65 , 80 , 128 ]:
553+ n = rng .getrandbits (bits ) | (1 << (bits - 1 ))
554+ with self .subTest (n = n ):
555+ self .assertRaises (OverflowError , isprime , n )
556+
557+ def test_isprime_integer_like (self ):
558+ isprime = self .module .isprime
559+ self .assertIs (isprime (False ), False )
560+ self .assertIs (isprime (True ), False )
561+ self .assertIs (isprime (IntSubclass (7 )), True )
562+ self .assertIs (isprime (IntSubclass (8 )), False )
563+ self .assertIs (isprime (MyIndexable (97 )), True )
564+ self .assertIs (isprime (MyIndexable (- 97 )), False )
565+
566+ def test_isprime_int_subclass_operators (self ):
567+ # Overridden operators of an int subclass must not affect the
568+ # result.
569+ isprime = self .module .isprime
570+ self .assertIs (isprime (BadIntSubclass (97 )), True )
571+ self .assertIs (isprime (BadIntSubclass (2 ** 61 - 1 )), True )
572+ self .assertIs (isprime (BadIntSubclass (2 ** 62 - 1 )), False )
573+
574+ def test_isprime_non_integers (self ):
575+ isprime = self .module .isprime
576+ for value in [7.0 , 7.5 , Decimal ('7' ), Fraction (7 , 1 ), '7' , 7.5j ]:
577+ with self .subTest (value = value ):
578+ self .assertRaises (TypeError , isprime , value )
579+ self .assertRaises (TypeError , isprime )
580+ self .assertRaises (TypeError , isprime , 7 , 11 )
581+
582+
583+ class PrimesIterTests (unittest .TestCase ):
584+ import math .integer as module
585+
586+ def test_primes (self ):
587+ primes = self .module .primes
588+ expected = primes_below (10 ** 4 )
589+ self .assertEqual (list (primes (stop = 10 ** 4 )), expected )
590+ self .assertEqual (len (expected ), 1229 )
591+ self .assertEqual (list (itertools .islice (primes (), 25 )), expected [:25 ])
592+
593+ def test_primes_start (self ):
594+ primes = self .module .primes
595+ for start in [- 10 ** 100 , - 100 , - 1 , 0 , 1 , 2 ]:
596+ with self .subTest (start = start ):
597+ self .assertEqual (list (primes (start , 10 )), [2 , 3 , 5 , 7 ])
598+ self .assertEqual (list (primes (3 , 10 )), [3 , 5 , 7 ])
599+ self .assertEqual (list (primes (4 , 10 )), [5 , 7 ])
600+ self .assertEqual (list (primes (8 , 12 )), [11 ])
601+ self .assertEqual (list (primes (9 , 12 )), [11 ])
602+ self .assertEqual (list (primes (7 , 8 )), [7 ])
603+
604+ def test_primes_stop (self ):
605+ primes = self .module .primes
606+ # The range is half-open.
607+ self .assertEqual (list (primes (2 , 2 )), [])
608+ self .assertEqual (list (primes (2 , 3 )), [2 ])
609+ self .assertEqual (list (primes (3 , 3 )), [])
610+ self .assertEqual (list (primes (7 , 7 )), [])
611+ self .assertEqual (list (primes (2 , - 10 )), [])
612+ self .assertEqual (list (primes (10 , 5 )), [])
613+ self .assertEqual (list (primes (stop = 0 )), [])
614+
615+ def test_primes_unbounded (self ):
616+ primes = self .module .primes
617+ it = primes ()
618+ self .assertEqual ([next (it ) for _ in range (5 )], [2 , 3 , 5 , 7 , 11 ])
619+ it = primes (10 ** 6 )
620+ self .assertEqual (next (it ), 1000003 )
621+
622+ def test_primes_huge (self ):
623+ primes = self .module .primes
624+ boundary = 10 ** 18
625+ expected = [n for n in range (boundary - 200 , boundary + 200 )
626+ if py_isprime (n )]
627+ self .assertEqual (list (primes (boundary - 200 , boundary + 200 )),
628+ expected )
629+ # The top of the supported range.
630+ expected = [n for n in range (2 ** 64 - 200 , 2 ** 64 ) if py_isprime (n )]
631+ self .assertEqual (list (primes (2 ** 64 - 200 , 2 ** 64 - 1 )), expected )
632+
633+ def test_primes_overflow (self ):
634+ primes = self .module .primes
635+ # The bounds must be less than 2**64.
636+ self .assertRaises (OverflowError , primes , 2 ** 64 )
637+ self .assertRaises (OverflowError , primes , 2 ** 64 + 100 , 2 ** 64 + 200 )
638+ self .assertRaises (OverflowError , primes , 0 , 2 ** 64 )
639+ self .assertRaises (OverflowError , primes , 10 ** 100 )
640+ # An unbounded iterator raises when it runs out of the
641+ # supported range.
642+ it = primes (2 ** 64 - 60 )
643+ self .assertEqual (next (it ), 2 ** 64 - 59 )
644+ self .assertRaises (OverflowError , next , it )
645+ self .assertRaises (StopIteration , next , it )
646+
647+ def test_primes_iterator_protocol (self ):
648+ primes = self .module .primes
649+ it = primes (2 , 10 )
650+ self .assertIs (iter (it ), it )
651+ self .assertEqual (list (it ), [2 , 3 , 5 , 7 ])
652+ # An exhausted iterator stays exhausted.
653+ self .assertEqual (list (it ), [])
654+ self .assertRaises (StopIteration , next , it )
655+ # The iterator type cannot be instantiated directly.
656+ self .assertRaises (TypeError , type (primes ()))
657+
658+ def test_primes_keywords (self ):
659+ primes = self .module .primes
660+ self .assertEqual (list (primes (start = 10 , stop = 30 )), [11 , 13 , 17 , 19 , 23 , 29 ])
661+ self .assertEqual (list (primes (10 , stop = 30 )), [11 , 13 , 17 , 19 , 23 , 29 ])
662+
663+ def test_primes_integer_like (self ):
664+ primes = self .module .primes
665+ self .assertEqual (list (primes (True , 10 )), [2 , 3 , 5 , 7 ])
666+ self .assertEqual (list (primes (IntSubclass (3 ), IntSubclass (10 ))), [3 , 5 , 7 ])
667+ self .assertEqual (list (primes (MyIndexable (3 ), MyIndexable (10 ))), [3 , 5 , 7 ])
668+ # The yielded values are exact ints.
669+ for p in primes (IntSubclass (3 ), IntSubclass (10 )):
670+ self .assertIs (type (p ), int )
671+
672+ def test_primes_int_subclass_operators (self ):
673+ # Overridden operators of an int subclass must not affect the
674+ # iteration.
675+ primes = self .module .primes
676+ self .assertEqual (list (primes (BadIntSubclass (3 ), BadIntSubclass (10 ))),
677+ [3 , 5 , 7 ])
678+ big = 10 ** 18
679+ self .assertEqual (list (primes (BadIntSubclass (big ), big + 100 )),
680+ [n for n in range (big , big + 100 ) if py_isprime (n )])
681+
682+ def test_primes_non_integers (self ):
683+ primes = self .module .primes
684+ self .assertRaises (TypeError , primes , 2.5 )
685+ self .assertRaises (TypeError , primes , 2.5 , 10 )
686+ self .assertRaises (TypeError , primes , 2 , 10.5 )
687+ self .assertRaises (TypeError , primes , '2' )
688+ self .assertRaises (TypeError , primes , 2 , '10' )
689+ self .assertRaises (TypeError , primes , 2 , 10 , 3 )
690+
691+
409692class MiscTests (unittest .TestCase ):
410693
411694 def test_module_name (self ):
@@ -416,6 +699,13 @@ def test_module_name(self):
416699 obj = getattr (math .integer , name )
417700 self .assertEqual (obj .__module__ , 'math.integer' )
418701
702+ def test_math_namespace (self ):
703+ # New functions are added only to math.integer, not to math
704+ # (PEP 791).
705+ import math
706+ self .assertFalse (hasattr (math , 'isprime' ))
707+ self .assertFalse (hasattr (math , 'primes' ))
708+
419709
420710if __name__ == '__main__' :
421711 unittest .main ()
0 commit comments