# partial unit test for gmpy mpz functionality
# relies on Tim Peters' "doctest.py" test-driver

r'''
>>> filter(lambda x: not x.startswith('_'), dir(_g))
['binary', 'bincoef', 'bit_length', 'cdivmod', 'ceil', 'comb', 'denom', 'digits', 'divexact', 'divm', 'f2q', 'fac', 'fbinary', 'fdigits', 'fdivmod', 'fib', 'floor', 'fround', 'fsign', 'fsqrt', 'gcd', 'gcdext', 'get_cache', 'getbit', 'getprec', 'getrprec', 'gmp_limbsize', 'gmp_version', 'hamdist', 'invert', 'is_power', 'is_prime', 'is_square', 'jacobi', 'kronecker', 'lcm', 'legendre', 'license', 'lowbits', 'mpf', 'mpir_version', 'mpq', 'mpz', 'next_prime', 'numdigits', 'numer', 'pi', 'popcount', 'qbinary', 'qdigits', 'qdiv', 'qsign', 'rand', 'reldiff', 'remove', 'root', 'scan0', 'scan1', 'set_cache', 'set_debug', 'set_fcoform', 'set_minprec', 'set_tagoff', 'setbit', 'sign', 'sqrt', 'sqrtrem', 'tdivmod', 'trunc', 'version']
>>> filter(lambda x: not x.startswith('__'), dir(a))
['_copy', 'binary', 'bincoef', 'bit_length', 'comb', 'digits', 'getbit', 'hamdist', 'invert', 'is_power', 'is_prime', 'is_square', 'jacobi', 'kronecker', 'legendre', 'lowbits', 'next_prime', 'numdigits', 'popcount', 'qdiv', 'remove', 'root', 'scan0', 'scan1', 'setbit', 'sign', 'sqrt', 'sqrtrem']
>>>
'''
import warnings
warnings.filterwarnings('ignore', 'setprec')

import gmpy as _g, doctest, sys, operator, gc
__test__={}
a=_g.mpz(123)
b=_g.mpz(456)

# Disable tests since they are not reliable with Python 3.1 but left behind
# in case it is needed in the future.

if sys.platform in ('__DISABLE__linux2', '__DISABLE__darwin'):
  def _memsize():
    """ this function tries to return a measurement of how much memory
        this process is consuming (if it doesn't manage to, it returns 0).
    """
    import os
    try: x = int(os.popen('ps -p %d -o vsz|tail -1' % os.getpid()).read())
    except: x = 0
    return x
else:
  def _memsize():
    return 0

def factorize(x):
    r'''
    >>> factorize(a)
    [3, 41]
    >>> factorize(b)
    [2, 2, 2, 3, 19]
    >>>
    '''
    import gmpy as _g
    savex=x
    prime=2
    x=_g.mpz(x)
    factors=[]
    while x>=prime:
        newx,mult=x.remove(prime)
        if mult:
            factors.extend([int(prime)]*mult)
            x=newx
        prime=_g.next_prime(prime)
    for factor in factors: assert _g.is_prime(factor)
    from operator import mul
    assert reduce(mul, factors)==savex
    return factors

if sys.version[:3] >= '2.5':
  __test__['index']=\
r'''
>>> range(333)[a]
123
>>> range(333)[b]
Traceback (innermost last):
  ...
IndexError: list index out of range
>>> ix = operator.index
>>> ix(_g.mpz(sys.maxint)) == sys.maxint
True
>>> type(ix(_g.mpz(sys.maxint))) is int
True
>>> ix(_g.mpz(sys.maxint+1)) == sys.maxint+1
True
>>> type(ix(_g.mpz(sys.maxint+1))) is long
True
'''

__test__['elemop']=\
r'''
>>> a+b
mpz(579)
>>> a-b
mpz(-333)
>>> a*b
mpz(56088)
>>> a/b
mpz(0)
>>> a%b
mpz(123)
>>> 0%b
mpz(0)
>>> b+a
mpz(579)
>>> b-a
mpz(333)
>>> b*a
mpz(56088)
>>> b%a
mpz(87)
>>> divmod(a,b)
(mpz(0), mpz(123))
>>> divmod(b,a)
(mpz(3), mpz(87))
>>> divmod(0,b)
(mpz(0), mpz(0))
>>> -a
mpz(-123)
>>> a+1
mpz(124)
>>> a+(-1)
mpz(122)
>>> (-1)+a
mpz(122)
>>> 1+a
mpz(124)
>>> a-1
mpz(122)
>>> a-(-1)
mpz(124)
>>> 1-a
mpz(-122)
>>> (-1)-a
mpz(-124)
>>> a+True
mpz(124)
>>> a+False
mpz(123)
>>> a*False
mpz(0)
>>> a//True
mpz(123)
>>> abs(-a)==a
1
>>> pow(a,10)
mpz(792594609605189126649L)
>>> pow(a,7,b)
mpz(99)
>>> _g.sign(b-a)
1
>>> _g.sign(b-b)
0
>>> _g.sign(a-b)
-1
>>> a.sign()
1
>>> (-a).sign()
-1
>>> z=b-b; z.sign()
0
>>> _g.mpz(4)**(0.5)
mpf('2.e0')
>>> import pickle
>>> pickle.loads(pickle.dumps(_g.mpz(12346789)))
mpz(12346789)
>>> s='12345678901234567890123456789'
>>> int(s) == _g.mpz(s)
True
>>> _g.mpz(s) == int(s)
True
>>> del s
'''

from gmpy_truediv import truediv
__test__['newdiv']=\
r'''
>>> a/b
mpz(0)
>>> a//b
mpz(0)
>>> truediv(a,b)
mpf('2.69736842105263157895e-1')
>>> b/a
mpz(3)
>>> b//a
mpz(3)
>>> truediv(b,a)
mpf('3.70731707317073170732e0')
>>>
'''

__test__['divexact']=\
r'''
>>> a=_g.mpz('1234567912345678912345679')
>>> b=_g.mpz('789789789789789789789789')
>>> c=a*b
>>> _g.divexact(c,a)
mpz(789789789789789789789789L)
>>> _g.divexact(10,0)
Traceback (most recent call last):
  ...
ZeroDivisionError: divexact() division by 0
>>>
'''

__test__['divmod']=\
r'''
>>> _g.cdivmod(17,5)
(mpz(4), mpz(-3))
>>> _g.cdivmod(-17,5)
(mpz(-3), mpz(-2))
>>> _g.cdivmod(17,-5)
(mpz(-3), mpz(2))
>>> _g.cdivmod(-17,-5)
(mpz(4), mpz(3))
>>> _g.fdivmod(17,5)
(mpz(3), mpz(2))
>>> _g.fdivmod(-17,5)
(mpz(-4), mpz(3))
>>> _g.fdivmod(17,-5)
(mpz(-4), mpz(-3))
>>> _g.fdivmod(-17,-5)
(mpz(3), mpz(-2))
>>> _g.tdivmod(17,5)
(mpz(3), mpz(2))
>>> _g.tdivmod(-17,5)
(mpz(-3), mpz(-2))
>>> _g.tdivmod(17,-5)
(mpz(-3), mpz(2))
>>> _g.tdivmod(-17,-5)
(mpz(3), mpz(-2))
>>> _g.cdivmod(10,0)
Traceback (most recent call last):
  ...
ZeroDivisionError: cdivmod() division by 0
>>> _g.fdivmod(10,0)
Traceback (most recent call last):
  ...
ZeroDivisionError: fdivmod() division by 0
>>> _g.tdivmod(10,0)
Traceback (most recent call last):
  ...
ZeroDivisionError: tdivmod() division by 0
'''

__test__['cmpr']=\
r'''
>>> c=_g.mpz(a)
>>> c is a
1
>>> c==a
1
>>> c>a
0
>>> c<a
0
>>> d=a._copy()
>>> a is d
0
>>> a == d
1
>>> cmp(a,c)
0
>>> cmp(a,b)
-1
>>> a>b
0
>>> a<b
1
>>> not _g.mpz(0)
1
>>> not a
0
>>> _g.mpz(1) == None
False
>>> _g.mpz(1) == '1'
False
>>> _g.mpz(1) == 'abc'
False
>>> [_g.mpz(23), None].count(None)
1
>>> _g.mpz(3.14)
mpz(3)
>>> _g.mpz(_g.mpq(17,3))
mpz(5)
>>> _g.mpz(23L)
mpz(23)
>>> _g.mpz(-23L)
mpz(-23)
>>> x=1000L*1000*1000*1000*1000*1000*1000
>>> _g.mpz(x)
mpz(1000000000000000000000L)
>>> try: print cmp(_g.mpz(1), _g.mpz(-1))
... except: print 'ouch!'
1
'''

__test__['special'] = \
r'''
>>> a == float('Inf')
False
>>> a != float('Inf')
True
>>> a > float('Inf')
False
>>> a >= float('Inf')
False
>>> a < float('Inf')
True
>>> a <= float('Inf')
True
>>> a == float('-Inf')
False
>>> a != float('-Inf')
True
>>> a > float('-Inf')
True
>>> a >= float('-Inf')
True
>>> a < float('-Inf')
False
>>> a <= float('-Inf')
False
>>> a == float('nan')
False
>>> a != float('nan')
True
>>> a > float('nan')
False
>>> a >= float('nan')
False
>>> a < float('nan')
False
>>> a <= float('nan')
False
>>> float('Inf') == a
False
>>> float('Inf') != a
True
>>> float('Inf') > a
True
>>> float('Inf') >= a
True
>>> float('Inf') < a
False
>>> float('Inf') <= a
False
>>> float('-Inf') == a
False
>>> float('-Inf') != a
True
>>> float('-Inf') > a
False
>>> float('-Inf') >= a
False
>>> float('-Inf') < a
True
>>> float('-Inf') <= a
True
>>> float('nan') == a
False
>>> float('nan') != a
True
>>> float('nan') > a
False
>>> float('nan') >= a
False
>>> float('nan') < a
False
>>> float('nan') <= a
False
>>> a + float('Inf')
inf
>>> float('Inf') + a
inf
>>> a + float('-Inf')
-inf
>>> float('-Inf') + a
-inf
>>> a + float('nan')
nan
>>> float('nan') + a
nan
>>> a - float('Inf')
-inf
>>> float('Inf') - a
inf
>>> a - float('-Inf')
inf
>>> float('-Inf') - a
-inf
>>> a - float('nan')
nan
>>> float('nan') - a
nan
>>> a * float('Inf')
inf
>>> float('Inf') * a
inf
>>> a * float('-Inf')
-inf
>>> float('-Inf') * a
-inf
>>> -a * float('Inf')
-inf
>>> float('Inf') * -a
-inf
>>> -a * float('-Inf')
inf
>>> float('-Inf') * -a
inf
>>> a * float('nan')
nan
>>> float('nan') * a
nan
>>> _g.mpz(0) * float('Inf')
nan
>>> _g.mpz(0) * float('-Inf')
nan
>>> float('Inf') * _g.mpz(0)
nan
>>> float('-Inf') * _g.mpz(0)
nan
>>> a / float('Inf')
mpf('0.e0')
>>> -a / float('Inf')
mpf('0.e0')
>>> float('Inf') / a
inf
>>> float('Inf') / -a
-inf
>>> a / float('-Inf')
mpf('0.e0')
>>> -a / float('-Inf')
mpf('0.e0')
>>> float('-Inf') / a
-inf
>>> float('-Inf') / -a
inf
>>> a / float('nan')
nan
>>> float('nan') / a
nan
>>> float('nan') / _g.mpz(0)
Traceback (most recent call last):
  ...
ZeroDivisionError: mpz division by zero
>>> divmod(a, float('Inf'))
(mpf('0.e0'), mpf('1.23e2'))
>>> divmod(a, float('-Inf'))
(mpf('-1.e0'), -inf)
>>> divmod(-a, float('Inf'))
(mpf('-1.e0'), inf)
>>> divmod(-a, float('-Inf'))
(mpf('0.e0'), mpf('-1.23e2'))
>>> divmod(a, float('nan'))
(nan, nan)
>>> divmod(-a, float('nan'))
(nan, nan)
>>> divmod(_g.mpz(0), float('Inf'))
(mpf('0.e0'), mpf('0.e0'))
>>> divmod(_g.mpz(0), float('-Inf'))
(mpf('0.e0'), mpf('0.e0'))
>>> divmod(_g.mpz(0), float('nan'))
(nan, nan)
>>> divmod(float('Inf'), a)
(nan, nan)
>>> divmod(float('-Inf'), a)
(nan, nan)
>>> divmod(float('Inf'), -a)
(nan, nan)
>>> divmod(float('-Inf'), -a)
(nan, nan)
>>> divmod(float('nan'), a)
(nan, nan)
>>> divmod(float('nan'), -a)
(nan, nan)
>>> divmod(float('Inf'), _g.mpz(0))
Traceback (most recent call last):
  ...
ZeroDivisionError: mpz modulo by zero
>>> divmod(float('-Inf'), _g.mpz(0))
Traceback (most recent call last):
  ...
ZeroDivisionError: mpz modulo by zero
>>> divmod(float('nan'), _g.mpz(0))
Traceback (most recent call last):
  ...
ZeroDivisionError: mpz modulo by zero
'''

__test__['bitops']=\
r'''
>>> ~a
mpz(-124)
>>> a&b
mpz(72)
>>> a|b
mpz(507)
>>> a^b
mpz(435)
>>> a<<1
mpz(246)
>>> a>>1
mpz(61)
>>> a<<-1
Traceback (innermost last):
  ...
ValueError: negative shift count
>>> a>>-2
Traceback (innermost last):
  ...
ValueError: negative shift count
>>> a<<0
mpz(123)
>>> a>>0
mpz(123)
>>> a.popcount()
6
>>> _g.popcount(b)
4
>>> _g.popcount(-7)
-1
>>> _g.popcount(0)
0
>>> a.hamdist(b)
6
>>> _g.hamdist(3)
Traceback (innermost last):
  ...
TypeError: hamdist() expects 'mpz','mpz' arguments
>>> a.hamdist()
Traceback (innermost last):
  ...
TypeError: hamdist() expects 'mpz','mpz' arguments
>>> a.hamdist(3, 4)
Traceback (innermost last):
  ...
TypeError: hamdist() expects 'mpz','mpz' arguments
>>> a.lowbits(5)
mpz(27)
>>> b.lowbits(5)
mpz(8)
>>> b.lowbits(5)==(b%32)
1
>>> a.lowbits(5)==(a%32)
1
>>> a.setbit(20)
mpz(1048699)
>>> a.setbit(0,0)
mpz(122)
>>> for i in range(8):
...     print a.getbit(i),
...     if i==7: print
...
1 1 0 1 1 1 1 0
>>> for i in range(10):
...     print b.getbit(i),
...     if i==9: print
...
0 0 0 1 0 0 1 1 1 0
>>> [a.scan0(j) for j in range(33)]
[2, 2, 2, 7, 7, 7, 7, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32]
>>> [a.scan1(j) for j in range(10)]
[0, 1, 3, 3, 4, 5, 6, None, None, None]
>>> n=_g.mpz(-(7+6*16+5*256+7*4092))
>>> [n.scan0(j) for j in range(18)]
[1, 1, 3, 3, 6, 6, 6, 8, 8, 10, 10, 12, 12, 13, 14, -1, None, None]
>>> [n.scan1(j) for j in range(33)]
[0, 2, 2, 4, 4, 5, 7, 7, 9, 9, 11, 11, 15, 15, 15, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32]
>>> _g.mpz(0).bit_length()
0
>>> _g.mpz(12345).bit_length()
14
'''

__test__['format']=\
r'''
>>> str(a)
'123'
>>> repr(a)
'mpz(123)'
>>> hex(a)
'0x7b'
>>> oct(a)
'0173'
>>> _g.mpz('123')
mpz(123)
>>> _g.mpz('1001001011',2)
mpz(587)
>>> _g.mpz('1001001011',2).digits(2)
'1001001011'
>>> for i in range(2,63):
...     print a.digits(i),
...     if i%6==0: print
...
1111011 11120 1323 443 323
234 173 146 123 102 a3
96 8b 83 7b 74 6f
69 63 5i 5d 58 53
4n 4j 4f 4b 47 43
3u 3r 3o 3l 3i 3f
3C 39 36 33 30 2d
2b 2Z 2X 2V 2T 2R
2P 2N 2L 2J 2H 2F
2D 2B 29 27 25 23
21 1z
>>> print a.digits(63)
Traceback (innermost last):
  File "<stdin>", line 1, in ?
    print a.digits(37)
ValueError: base must be either 0 or in the interval 2 ... 62
>>> _g.set_tagoff(0)
1
>>> a
gmpy.mpz(123)
>>> _g.set_tagoff(1)
0
>>> _g.mpz('43')
mpz(43)
>>> _g.mpz('043')
mpz(43)
>>> _g.mpz('43',0)
mpz(43)
>>> _g.mpz('043',0)
mpz(35)
>>> _g.mpz('0x43',0)
mpz(67)
>>> _g.mpz('0x43')
Traceback (innermost last):
  File "<pyshell#181>", line 1, in ?
    _g.mpz('0x43')
ValueError: invalid digits
>>>
'''

__test__['binio']=\
r'''
>>> ba=a.binary()
>>> ba
'{'
>>> _g.mpz(ba,256)
mpz(123)
>>> _g.mpz(ba,256)==a
1
>>> _g.binary(123)
'{'
>>> z=_g.mpz('melancholy',256)
>>> z
mpz(573406620562849222387053L)
>>> long(z)
573406620562849222387053L
>>> divmod(z,a)
(mpz(4661842443600400182008L), mpz(69))
>>> for i in range(2,63):
...    print i,z.numdigits(i),
...    if i%6==0: print
...
2 79 3 50 4 40 5 35 6 31
7 29 8 27 9 25 10 24 11 23 12 23
13 22 14 21 15 21 16 20 17 20 18 19
19 19 20 19 21 18 22 18 23 18 24 18
25 18 26 17 27 17 28 17 29 17 30 17
31 16 32 16 33 16 34 16 35 16 36 16
37 16 38 16 39 15 40 15 41 15 42 15
43 15 44 15 45 15 46 15 47 15 48 15
49 15 50 14 51 14 52 14 53 14 54 14
55 14 56 14 57 14 58 14 59 14 60 14
61 14 62 14
>>> _g.numdigits(23)
2
>>> _g.numdigits(23,2)
5
>>> _g.numdigits(23,99)
Traceback (most recent call last):
  File "<string>", line 1, in ?
ValueError: base must be either 0 or in the interval 2 ... 62
>>> hash(a)
123
>>> hash(b)
456
>>> hash(z) == hash(long(z))
True
>>> _g.mpz(_g.binary(-123),256)
mpz(-123)
>>> long(_g.mpz(-3))
-3L
>>>
'''

__test__['number']=\
r'''
>>> print a.sqrt(), b.sqrt()
11 21
>>> print a.sqrtrem(), b.sqrtrem()
(mpz(11), mpz(2)) (mpz(21), mpz(15))
>>> for i in range(5):
...    print a.root(i+1),b.root(i+1)
...
(mpz(123), 1) (mpz(456), 1)
(mpz(11), 0) (mpz(21), 0)
(mpz(4), 0) (mpz(7), 0)
(mpz(3), 0) (mpz(4), 0)
(mpz(2), 0) (mpz(3), 0)
>>> a.is_square()
0
>>> a.is_power()
0
>>> _g.is_square(99*99)
1
>>> _g.is_square(99*99*99)
0
>>> _g.is_square(0)
1
>>> _g.is_square(-1)
0
>>> _g.is_power(99*99*99)
1
>>> _g.gcd(a,b)
mpz(3)
>>> temp=_g.gcdext(a,b)
>>> temp[0]==a*temp[1]+b*temp[2]
True
>>> _g.lcm(a,b)
mpz(18696)
>>> _g.fac(7)
mpz(5040)
>>> _g.fib(17)
mpz(1597)
>>> for i in range(10):
...     print _g.bincoef(10,i)
...
1
10
45
120
210
252
210
120
45
10
>>> _g.divm(b,a,20)
mpz(12)
>>> _g.divm(a,b,100)
Traceback (innermost last):
  File "<pyshell#184>", line 1, in ?
    _g.divm(a,b,100)
ZeroDivisionError: not invertible
>>> _g.divm(6,12,14)
mpz(4)
>>> _g.divm(0,1,2)
mpz(0)
>>> # guard against regression of an ancient gmpy bug: divm w/non-coprime parms
>>> _g.divm(4,8,20)
mpz(3)
>>> _g.divm(4,8,20)
mpz(3)
>>> _g.mpz(20)
mpz(20)
>>> _g.mpz(8)
mpz(8)
>>> _g.mpz(4)
mpz(4)
>>> # guard against regression of a memory leak in divm
>>> __ = gc.collect()
>>> _siz = 87654
>>> _siz = _memsize()
>>> for x in xrange(45678):
...     _xx=_g.divm(b,a,20)
>>> del _xx
>>> __ = gc.collect()
>>> (_memsize()-_siz) <= 16
True
>>> a.invert(100)
mpz(87)
>>> b.invert(100)
mpz(0)
>>> _g.invert(3)
Traceback (innermost last):
  ...
TypeError: invert() expects 'mpz','mpz' arguments
>>> a.invert()
Traceback (innermost last):
  ...
TypeError: invert() expects 'mpz','mpz' arguments
>>> a.invert(3, 4)
Traceback (innermost last):
  ...
TypeError: invert() expects 'mpz','mpz' arguments
>>> _g.comb(3,-1)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
ValueError: binomial coefficient with negative k
>>> _g.sqrt(-1)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
ValueError: sqrt of negative number
>>> _g.sqrtrem(-1)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
ValueError: sqrt of negative number
>>> _g.remove(3,-1)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
ValueError: factor must be > 1
>>> _g.remove(3)
Traceback (innermost last):
  ...
TypeError: remove() expects 'mpz','mpz' arguments
>>> a.remove()
Traceback (innermost last):
  ...
TypeError: remove() expects 'mpz','mpz' arguments
>>> a.remove(3, 4)
Traceback (innermost last):
  ...
TypeError: remove() expects 'mpz','mpz' arguments
>>> _g.is_prime(3,-3)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
ValueError: repetition count for is_prime must be positive
>>> _g.jacobi(10,3)
1
>>> _g.jacobi(10,-3)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
ValueError: jacobi's y must be odd prime > 0
>>> _g.jacobi(3)
Traceback (innermost last):
  ...
TypeError: jacobi() expects 'mpz','mpz' arguments
>>> a.jacobi()
Traceback (innermost last):
  ...
TypeError: jacobi() expects 'mpz','mpz' arguments
>>> a.jacobi(3, 4)
Traceback (innermost last):
  ...
TypeError: jacobi() expects 'mpz','mpz' arguments
>>> _g.legendre(10,3)
1
>>> _g.legendre(10,-3)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
ValueError: legendre's y must be odd and > 0
>>> _g.legendre(3)
Traceback (innermost last):
  ...
TypeError: legendre() expects 'mpz','mpz' arguments
>>> a.legendre()
Traceback (innermost last):
  ...
TypeError: legendre() expects 'mpz','mpz' arguments
>>> a.legendre(3, 4)
Traceback (innermost last):
  ...
TypeError: legendre() expects 'mpz','mpz' arguments
>>> _g.kronecker(10,3)
1
>>> _g.kronecker(10,-3)
1
>>> _g.kronecker(3)
Traceback (innermost last):
  ...
TypeError: kronecker() expects 'mpz','mpz' arguments
>>> a.kronecker()
Traceback (innermost last):
  ...
TypeError: kronecker() expects 'mpz','mpz' arguments
>>> a.kronecker(3, 4)
Traceback (innermost last):
  ...
TypeError: kronecker() expects 'mpz','mpz' arguments
>>> a=10L**20
>>> b=a+39
>>> _g.jacobi(a,b)
1
>>> _g.legendre(a,b)
1
>>> _g.kronecker(a,b)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
ValueError: Either arg in Kronecker must fit in an int
>>> f=_g.mpf(3.3)
>>> f.setprec(-1)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
ValueError: n must be >=0
>>> _g.rand('init',-1)
>>> _g.rand('init',-7)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
ValueError: size must be in 1..128
>>> _g.rand('init',200)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
ValueError: size must be in 1..128
>>> _g.rand('qual')
32
>>> _g.rand('floa',-7)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
ValueError: 'floa' needs arg>=0
'''

def _test(chat=None):
    try:
        float('nan')
    except ValueError:
        if "special" in __test__:
            del(__test__["special"])

    if chat:
        print "Unit tests for gmpy 1.17 (mpz functionality)"
        print "    running on Python %s" % sys.version
        print
        if _g.gmp_version():
            print "Testing gmpy %s (GMP %s) with default caching (%s, %s)" % (
                (_g.version(), _g.gmp_version(), _g.get_cache()[0],
                _g.get_cache()[1]))
        else:
            print "Testing gmpy %s (MPIR %s) with default caching (%s, %s)" % (
                (_g.version(), _g.mpir_version(), _g.get_cache()[0],
                _g.get_cache()[1]))

    thismod = sys.modules.get(__name__)
    doctest.testmod(thismod, report=0)

    if chat: print "Repeating tests, with caching disabled"
    _g.set_cache(0,128)

    sav = sys.stdout
    class _Dummy:
        def write(self,*whatever):
            pass
    try:
        sys.stdout = _Dummy()
        doctest.testmod(thismod, report=0)
    finally:
        sys.stdout = sav

    if chat:
        print
        print "Overall results for mpz:"
    return doctest.master.summarize(chat)


if __name__=='__main__':
    _test(1)

