Commit e9ba3705 authored by Pablo Galindo's avatar Pablo Galindo Committed by GitHub

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.
parent 65fc98e7
...@@ -5,6 +5,7 @@ from test.support import run_unittest, verbose, requires_IEEE_754 ...@@ -5,6 +5,7 @@ from test.support import run_unittest, verbose, requires_IEEE_754
from test import support from test import support
import unittest import unittest
import itertools import itertools
import decimal
import math import math
import os import os
import platform import platform
...@@ -510,6 +511,10 @@ class MathTests(unittest.TestCase): ...@@ -510,6 +511,10 @@ class MathTests(unittest.TestCase):
self.assertRaises(ValueError, math.factorial, -1e100) self.assertRaises(ValueError, math.factorial, -1e100)
self.assertRaises(ValueError, math.factorial, math.pi) 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. # Other implementations may place different upper bounds.
@support.cpython_only @support.cpython_only
def testFactorialHugeInputs(self): def testFactorialHugeInputs(self):
......
``math.factorial`` no longer accepts arguments that are not int-like.
Patch by Pablo Galindo.
...@@ -1656,7 +1656,7 @@ math_factorial(PyObject *module, PyObject *arg) ...@@ -1656,7 +1656,7 @@ math_factorial(PyObject *module, PyObject *arg)
{ {
long x; long x;
int overflow; int overflow;
PyObject *result, *odd_part, *two_valuation; PyObject *result, *odd_part, *two_valuation, *pyint_form;
if (PyFloat_Check(arg)) { if (PyFloat_Check(arg)) {
PyObject *lx; PyObject *lx;
...@@ -1672,8 +1672,14 @@ math_factorial(PyObject *module, PyObject *arg) ...@@ -1672,8 +1672,14 @@ math_factorial(PyObject *module, PyObject *arg)
x = PyLong_AsLongAndOverflow(lx, &overflow); x = PyLong_AsLongAndOverflow(lx, &overflow);
Py_DECREF(lx); Py_DECREF(lx);
} }
else else {
x = PyLong_AsLongAndOverflow(arg, &overflow); 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()) { if (x == -1 && PyErr_Occurred()) {
return NULL; return NULL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment