Issue #12909: Make PyLong_As* functions consistent in their use of exceptions.
PyLong_AsDouble() and PyLong_AsUnsignedLongLong() now raise TypeError (rather than SystemError) when passed a non-integer argument, matching the behavior of all the other PyLong_As*() functions.
This commit is contained in:
parent
425fcd3045
commit
3d5881ec2b
|
@ -769,6 +769,68 @@ test_long_long_and_overflow(PyObject *self)
|
||||||
return Py_None;
|
return Py_None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Test the PyLong_As{Size,Ssize}_t API. At present this just tests that
|
||||||
|
non-integer arguments are handled correctly. It should be extended to
|
||||||
|
test overflow handling.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
test_long_as_size_t(PyObject *self)
|
||||||
|
{
|
||||||
|
size_t out_u;
|
||||||
|
Py_ssize_t out_s;
|
||||||
|
|
||||||
|
Py_INCREF(Py_None);
|
||||||
|
|
||||||
|
out_u = PyLong_AsSize_t(Py_None);
|
||||||
|
if (out_u != (size_t)-1 || !PyErr_Occurred())
|
||||||
|
return raiseTestError("test_long_as_size_t",
|
||||||
|
"PyLong_AsSize_t(None) didn't complain");
|
||||||
|
if (!PyErr_ExceptionMatches(PyExc_TypeError))
|
||||||
|
return raiseTestError("test_long_as_size_t",
|
||||||
|
"PyLong_AsSize_t(None) raised "
|
||||||
|
"something other than TypeError");
|
||||||
|
PyErr_Clear();
|
||||||
|
|
||||||
|
out_s = PyLong_AsSsize_t(Py_None);
|
||||||
|
if (out_s != (Py_ssize_t)-1 || !PyErr_Occurred())
|
||||||
|
return raiseTestError("test_long_as_size_t",
|
||||||
|
"PyLong_AsSsize_t(None) didn't complain");
|
||||||
|
if (!PyErr_ExceptionMatches(PyExc_TypeError))
|
||||||
|
return raiseTestError("test_long_as_size_t",
|
||||||
|
"PyLong_AsSsize_t(None) raised "
|
||||||
|
"something other than TypeError");
|
||||||
|
PyErr_Clear();
|
||||||
|
|
||||||
|
/* Py_INCREF(Py_None) omitted - we already have a reference to it. */
|
||||||
|
return Py_None;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Test the PyLong_AsDouble API. At present this just tests that
|
||||||
|
non-integer arguments are handled correctly.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
test_long_as_double(PyObject *self)
|
||||||
|
{
|
||||||
|
double out;
|
||||||
|
|
||||||
|
Py_INCREF(Py_None);
|
||||||
|
|
||||||
|
out = PyLong_AsDouble(Py_None);
|
||||||
|
if (out != -1.0 || !PyErr_Occurred())
|
||||||
|
return raiseTestError("test_long_as_double",
|
||||||
|
"PyLong_AsDouble(None) didn't complain");
|
||||||
|
if (!PyErr_ExceptionMatches(PyExc_TypeError))
|
||||||
|
return raiseTestError("test_long_as_double",
|
||||||
|
"PyLong_AsDouble(None) raised "
|
||||||
|
"something other than TypeError");
|
||||||
|
PyErr_Clear();
|
||||||
|
|
||||||
|
/* Py_INCREF(Py_None) omitted - we already have a reference to it. */
|
||||||
|
return Py_None;
|
||||||
|
}
|
||||||
|
|
||||||
/* Test the L code for PyArg_ParseTuple. This should deliver a PY_LONG_LONG
|
/* Test the L code for PyArg_ParseTuple. This should deliver a PY_LONG_LONG
|
||||||
for both long and int arguments. The test may leak a little memory if
|
for both long and int arguments. The test may leak a little memory if
|
||||||
it fails.
|
it fails.
|
||||||
|
@ -2267,6 +2329,8 @@ static PyMethodDef TestMethods[] = {
|
||||||
{"test_long_api", (PyCFunction)test_long_api, METH_NOARGS},
|
{"test_long_api", (PyCFunction)test_long_api, METH_NOARGS},
|
||||||
{"test_long_and_overflow", (PyCFunction)test_long_and_overflow,
|
{"test_long_and_overflow", (PyCFunction)test_long_and_overflow,
|
||||||
METH_NOARGS},
|
METH_NOARGS},
|
||||||
|
{"test_long_as_double", (PyCFunction)test_long_as_double,METH_NOARGS},
|
||||||
|
{"test_long_as_size_t", (PyCFunction)test_long_as_size_t,METH_NOARGS},
|
||||||
{"test_long_numbits", (PyCFunction)test_long_numbits, METH_NOARGS},
|
{"test_long_numbits", (PyCFunction)test_long_numbits, METH_NOARGS},
|
||||||
{"test_k_code", (PyCFunction)test_k_code, METH_NOARGS},
|
{"test_k_code", (PyCFunction)test_k_code, METH_NOARGS},
|
||||||
{"test_empty_argparse", (PyCFunction)test_empty_argparse,METH_NOARGS},
|
{"test_empty_argparse", (PyCFunction)test_empty_argparse,METH_NOARGS},
|
||||||
|
|
|
@ -177,6 +177,32 @@ TESTNAME(PyObject *error(const char*))
|
||||||
Py_DECREF(one);
|
Py_DECREF(one);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Test F_PY_TO_{S,U} on non-pylong input. This should raise a TypeError. */
|
||||||
|
{
|
||||||
|
TYPENAME out;
|
||||||
|
unsigned TYPENAME uout;
|
||||||
|
|
||||||
|
Py_INCREF(Py_None);
|
||||||
|
|
||||||
|
out = F_PY_TO_S(Py_None);
|
||||||
|
if (out != (TYPENAME)-1 || !PyErr_Occurred())
|
||||||
|
return error("PyLong_AsXXX(None) didn't complain");
|
||||||
|
if (!PyErr_ExceptionMatches(PyExc_TypeError))
|
||||||
|
return error("PyLong_AsXXX(None) raised "
|
||||||
|
"something other than TypeError");
|
||||||
|
PyErr_Clear();
|
||||||
|
|
||||||
|
uout = F_PY_TO_U(Py_None);
|
||||||
|
if (uout != (unsigned TYPENAME)-1 || !PyErr_Occurred())
|
||||||
|
return error("PyLong_AsXXX(None) didn't complain");
|
||||||
|
if (!PyErr_ExceptionMatches(PyExc_TypeError))
|
||||||
|
return error("PyLong_AsXXX(None) raised "
|
||||||
|
"something other than TypeError");
|
||||||
|
PyErr_Clear();
|
||||||
|
|
||||||
|
Py_DECREF(Py_None);
|
||||||
|
}
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_INCREF(Py_None);
|
||||||
return Py_None;
|
return Py_None;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1193,10 +1193,14 @@ PyLong_AsUnsignedLongLong(PyObject *vv)
|
||||||
int one = 1;
|
int one = 1;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
if (vv == NULL || !PyLong_Check(vv)) {
|
if (vv == NULL) {
|
||||||
PyErr_BadInternalCall();
|
PyErr_BadInternalCall();
|
||||||
return (unsigned PY_LONG_LONG)-1;
|
return (unsigned PY_LONG_LONG)-1;
|
||||||
}
|
}
|
||||||
|
if (!PyLong_Check(vv)) {
|
||||||
|
PyErr_SetString(PyExc_TypeError, "an integer is required");
|
||||||
|
return (unsigned PY_LONG_LONG)-1;
|
||||||
|
}
|
||||||
|
|
||||||
v = (PyLongObject*)vv;
|
v = (PyLongObject*)vv;
|
||||||
switch(Py_SIZE(v)) {
|
switch(Py_SIZE(v)) {
|
||||||
|
@ -2481,10 +2485,14 @@ PyLong_AsDouble(PyObject *v)
|
||||||
Py_ssize_t exponent;
|
Py_ssize_t exponent;
|
||||||
double x;
|
double x;
|
||||||
|
|
||||||
if (v == NULL || !PyLong_Check(v)) {
|
if (v == NULL) {
|
||||||
PyErr_BadInternalCall();
|
PyErr_BadInternalCall();
|
||||||
return -1.0;
|
return -1.0;
|
||||||
}
|
}
|
||||||
|
if (!PyLong_Check(v)) {
|
||||||
|
PyErr_SetString(PyExc_TypeError, "an integer is required");
|
||||||
|
return -1.0;
|
||||||
|
}
|
||||||
x = _PyLong_Frexp((PyLongObject *)v, &exponent);
|
x = _PyLong_Frexp((PyLongObject *)v, &exponent);
|
||||||
if ((x == -1.0 && PyErr_Occurred()) || exponent > DBL_MAX_EXP) {
|
if ((x == -1.0 && PyErr_Occurred()) || exponent > DBL_MAX_EXP) {
|
||||||
PyErr_SetString(PyExc_OverflowError,
|
PyErr_SetString(PyExc_OverflowError,
|
||||||
|
|
Loading…
Reference in New Issue