From: Pablo Galindo Date: Mon, 3 Sep 2018 21:20:06 +0000 (+0100) Subject: bpo-33083 - Make math.factorial reject arguments that are not int-like (GH-6149) X-Git-Tag: v3.8.0a1~1108 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e9ba3705de656215d52b8f8f4a2e7ad60190e944;p=thirdparty%2FPython%2Fcpython.git bpo-33083 - Make math.factorial reject arguments that are not int-like (GH-6149) math.factorial() was accepting non-integral Decimal instances. This is inconsistent with the actual behaviour for floats, which are not accepted. --- diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index fff82fe7fadb..608789f7202f 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -5,6 +5,7 @@ from test.support import run_unittest, verbose, requires_IEEE_754 from test import support import unittest import itertools +import decimal import math import os import platform @@ -510,6 +511,10 @@ class MathTests(unittest.TestCase): 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)) + self.assertRaises(TypeError, math.factorial, "5") + # Other implementations may place different upper bounds. @support.cpython_only def testFactorialHugeInputs(self): diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-03-19-00-59-20.bpo-33083.Htztjl.rst b/Misc/NEWS.d/next/Core and Builtins/2018-03-19-00-59-20.bpo-33083.Htztjl.rst new file mode 100644 index 000000000000..81df83989e48 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-03-19-00-59-20.bpo-33083.Htztjl.rst @@ -0,0 +1,2 @@ +``math.factorial`` no longer accepts arguments that are not int-like. +Patch by Pablo Galindo. diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index 06a969cebacb..e872e473f5fe 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -1656,7 +1656,7 @@ math_factorial(PyObject *module, PyObject *arg) { long x; int overflow; - PyObject *result, *odd_part, *two_valuation; + PyObject *result, *odd_part, *two_valuation, *pyint_form; if (PyFloat_Check(arg)) { PyObject *lx; @@ -1672,8 +1672,14 @@ math_factorial(PyObject *module, PyObject *arg) x = PyLong_AsLongAndOverflow(lx, &overflow); Py_DECREF(lx); } - else - x = PyLong_AsLongAndOverflow(arg, &overflow); + else { + pyint_form = PyNumber_Index(arg); + if (pyint_form == NULL) { + return NULL; + } + x = PyLong_AsLongAndOverflow(pyint_form, &overflow); + Py_DECREF(pyint_form); + } if (x == -1 && PyErr_Occurred()) { return NULL;