[pypy-commit] pypy math-improvements: Test for int_pow, test+fix for pow ValueError with third argument as 0

stian pypy.commits at gmail.com
Mon Nov 20 09:02:15 EST 2017


Author: stian
Branch: math-improvements
Changeset: r93094:9291ee92df89
Date: 2017-11-20 15:01 +0100
http://bitbucket.org/pypy/pypy/changeset/9291ee92df89/

Log:	Test for int_pow, test+fix for pow ValueError with third argument as
	0

diff --git a/pypy/objspace/std/test/test_longobject.py b/pypy/objspace/std/test/test_longobject.py
--- a/pypy/objspace/std/test/test_longobject.py
+++ b/pypy/objspace/std/test/test_longobject.py
@@ -192,6 +192,12 @@
         assert pow(x, 0L, 1L) == 0L
         assert pow(-1L, -1L) == -1.0
 
+    def test_int_pow(self):
+        x = 2L
+        assert pow(x, 2) == 4L
+        assert pow(x, 2, 2) == 0L
+        assert pow(x, 2, 3L) == 1L
+
     def test_getnewargs(self):
         assert  0L .__getnewargs__() == (0L,)
         assert  (-1L) .__getnewargs__() == (-1L,)
diff --git a/rpython/rlib/rbigint.py b/rpython/rlib/rbigint.py
--- a/rpython/rlib/rbigint.py
+++ b/rpython/rlib/rbigint.py
@@ -987,9 +987,7 @@
 
         size_b = UDIGIT_TYPE(b.numdigits())
 
-        if b.sign == 0:
-            return ONERBIGINT
-        elif c is not None:
+        if c is not None:
             if c.sign == 0:
                 raise ValueError("pow() 3rd argument cannot be 0")
 
@@ -1016,6 +1014,8 @@
             # so we only do it when it buys something.
             if a.sign < 0 or a.numdigits() > c.numdigits():
                 a = a.mod(c)
+        elif b.sign == 0:
+            return ONERBIGINT
         elif a.sign == 0:
             return NULLRBIGINT
         elif size_b == 1:
@@ -1124,9 +1124,7 @@
             raise ValueError("bigint pow() too negative")
 
         assert b >= 0
-        if b == 0:
-            return ONERBIGINT
-        elif c is not None:
+        if c is not None:
             if c.sign == 0:
                 raise ValueError("pow() 3rd argument cannot be 0")
 
@@ -1153,6 +1151,8 @@
             # so we only do it when it buys something.
             if a.sign < 0 or a.numdigits() > c.numdigits():
                 a = a.mod(c)
+        elif b == 0:
+            return ONERBIGINT
         elif a.sign == 0:
             return NULLRBIGINT
         elif b == 1:
diff --git a/rpython/rlib/test/test_rbigint.py b/rpython/rlib/test/test_rbigint.py
--- a/rpython/rlib/test/test_rbigint.py
+++ b/rpython/rlib/test/test_rbigint.py
@@ -190,7 +190,12 @@
                 r4 = pow(op1, op2, 1000)
                 print op1, op2
                 assert r3.tolong() == r4
-                
+
+    def test_pow_raises(self):
+        r1 = rbigint.fromint(2)
+        r0 = rbigint.fromint(0)
+        py.test.raises(ValueError, r1.int_pow, 2, r0)
+        py.test.raises(ValueError, r1.pow, r1, r0)
     def test_touint(self):
         result = r_uint(sys.maxint + 42)
         rl = rbigint.fromint(sys.maxint).add(rbigint.fromint(42))


More information about the pypy-commit mailing list