bpo-36027: Extend three-argument pow to negative second argument (GH-13266)
diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py
index e32fb75..b536cec 100644
--- a/Lib/test/test_builtin.py
+++ b/Lib/test/test_builtin.py
@@ -1195,7 +1195,8 @@
self.assertAlmostEqual(pow(-1, 0.5), 1j)
self.assertAlmostEqual(pow(-1, 1/3), 0.5 + 0.8660254037844386j)
- self.assertRaises(ValueError, pow, -1, -2, 3)
+ # See test_pow for additional tests for three-argument pow.
+ self.assertEqual(pow(-1, -2, 3), 1)
self.assertRaises(ValueError, pow, 1, 2, 0)
self.assertRaises(TypeError, pow)
diff --git a/Lib/test/test_pow.py b/Lib/test/test_pow.py
index cac1ae5..660ff80 100644
--- a/Lib/test/test_pow.py
+++ b/Lib/test/test_pow.py
@@ -1,3 +1,4 @@
+import math
import unittest
class PowTest(unittest.TestCase):
@@ -119,5 +120,30 @@
eq(pow(a, -fiveto), expected)
eq(expected, 1.0) # else we didn't push fiveto to evenness
+ def test_negative_exponent(self):
+ for a in range(-50, 50):
+ for m in range(-50, 50):
+ with self.subTest(a=a, m=m):
+ if m != 0 and math.gcd(a, m) == 1:
+ # Exponent -1 should give an inverse, with the
+ # same sign as m.
+ inv = pow(a, -1, m)
+ self.assertEqual(inv, inv % m)
+ self.assertEqual((inv * a - 1) % m, 0)
+
+ # Larger exponents
+ self.assertEqual(pow(a, -2, m), pow(inv, 2, m))
+ self.assertEqual(pow(a, -3, m), pow(inv, 3, m))
+ self.assertEqual(pow(a, -1001, m), pow(inv, 1001, m))
+
+ else:
+ with self.assertRaises(ValueError):
+ pow(a, -1, m)
+ with self.assertRaises(ValueError):
+ pow(a, -2, m)
+ with self.assertRaises(ValueError):
+ pow(a, -1001, m)
+
+
if __name__ == "__main__":
unittest.main()