diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2019-06-17 13:57:27 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-06-17 13:57:27 (GMT) |
commit | 231aad38493c871dd32930a21d256cbacd2ae20c (patch) | |
tree | 93c8e378e647443dcbcbc25b2c35e9052bcbef31 | |
parent | 1ce2656f13e726b3b99d4c968926908cff1f460a (diff) | |
download | cpython-231aad38493c871dd32930a21d256cbacd2ae20c.zip cpython-231aad38493c871dd32930a21d256cbacd2ae20c.tar.gz cpython-231aad38493c871dd32930a21d256cbacd2ae20c.tar.bz2 |
bpo-37315: Deprecate accepting floats in math.factorial(). (GH-14147)
-rw-r--r-- | Doc/library/math.rst | 3 | ||||
-rw-r--r-- | Doc/whatsnew/3.9.rst | 5 | ||||
-rw-r--r-- | Lib/test/test_math.py | 19 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Library/2019-06-17-11-59-52.bpo-37315.o1xFC0.rst | 2 | ||||
-rw-r--r-- | Modules/mathmodule.c | 6 |
5 files changed, 28 insertions, 7 deletions
diff --git a/Doc/library/math.rst b/Doc/library/math.rst index ff937d2..bfce41a 100644 --- a/Doc/library/math.rst +++ b/Doc/library/math.rst @@ -71,6 +71,9 @@ Number-theoretic and representation functions Return *x* factorial as an integer. Raises :exc:`ValueError` if *x* is not integral or is negative. + .. deprecated:: 3.9 + Accepting floats with integral values (like ``5.0``) is deprecated. + .. function:: floor(x) diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst index 62b013f..c5cb626 100644 --- a/Doc/whatsnew/3.9.rst +++ b/Doc/whatsnew/3.9.rst @@ -109,6 +109,11 @@ Build and C API Changes Deprecated ========== +* Currently :func:`math.factorial` accepts :class:`float` instances with + non-negative integer values (like ``5.0``). It raises a :exc:`ValueError` + for non-integral and negative floats. It is deprecated now. In future + Python versions it will raise a :exc:`TypeError` for all floats. + (Contributed by Serhiy Storchaka in :issue:`37315`.) Removed diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index adefa07..f259139 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -501,21 +501,25 @@ class MathTests(unittest.TestCase): def testFactorial(self): self.assertEqual(math.factorial(0), 1) - self.assertEqual(math.factorial(0.0), 1) total = 1 for i in range(1, 1000): total *= i self.assertEqual(math.factorial(i), total) - self.assertEqual(math.factorial(float(i)), total) self.assertEqual(math.factorial(i), py_factorial(i)) self.assertRaises(ValueError, math.factorial, -1) - self.assertRaises(ValueError, math.factorial, -1.0) self.assertRaises(ValueError, math.factorial, -10**100) - self.assertRaises(ValueError, math.factorial, -1e100) - self.assertRaises(ValueError, math.factorial, math.pi) def testFactorialNonIntegers(self): - self.assertRaises(TypeError, math.factorial, decimal.Decimal(5.2)) + with self.assertWarns(DeprecationWarning): + self.assertEqual(math.factorial(5.0), 120) + with self.assertWarns(DeprecationWarning): + self.assertRaises(ValueError, math.factorial, 5.2) + with self.assertWarns(DeprecationWarning): + self.assertRaises(ValueError, math.factorial, -1.0) + with self.assertWarns(DeprecationWarning): + self.assertRaises(ValueError, math.factorial, -1e100) + self.assertRaises(TypeError, math.factorial, decimal.Decimal('5')) + self.assertRaises(TypeError, math.factorial, decimal.Decimal('5.2')) self.assertRaises(TypeError, math.factorial, "5") # Other implementations may place different upper bounds. @@ -524,7 +528,8 @@ class MathTests(unittest.TestCase): # Currently raises ValueError for inputs that are too large # to fit into a C long. self.assertRaises(OverflowError, math.factorial, 10**100) - self.assertRaises(OverflowError, math.factorial, 1e100) + with self.assertWarns(DeprecationWarning): + self.assertRaises(OverflowError, math.factorial, 1e100) def testFloor(self): self.assertRaises(TypeError, math.floor) diff --git a/Misc/NEWS.d/next/Library/2019-06-17-11-59-52.bpo-37315.o1xFC0.rst b/Misc/NEWS.d/next/Library/2019-06-17-11-59-52.bpo-37315.o1xFC0.rst new file mode 100644 index 0000000..fd59819 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-06-17-11-59-52.bpo-37315.o1xFC0.rst @@ -0,0 +1,2 @@ +Deprecated accepting floats with integral value (like ``5.0``) in +:func:`math.factorial`. diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index 82a9a14..a75a3c9 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -1981,6 +1981,12 @@ math_factorial(PyObject *module, PyObject *arg) PyObject *result, *odd_part, *pyint_form; if (PyFloat_Check(arg)) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Using factorial() with floats is deprecated", + 1) < 0) + { + return NULL; + } PyObject *lx; double dx = PyFloat_AS_DOUBLE((PyFloatObject *)arg); if (!(Py_IS_FINITE(dx) && dx == floor(dx))) { |