diff options
author | Mark Dickinson <dickinsm@gmail.com> | 2010-01-30 10:30:15 (GMT) |
---|---|---|
committer | Mark Dickinson <dickinsm@gmail.com> | 2010-01-30 10:30:15 (GMT) |
commit | 93f562c4f9a751034616068468e7dc2cfd022275 (patch) | |
tree | 5f41dda113e687676341b3032abc0545c5c4543e /Modules | |
parent | a79b75743af3d7c66fcccc1c47699c838422064b (diff) | |
download | cpython-93f562c4f9a751034616068468e7dc2cfd022275.zip cpython-93f562c4f9a751034616068468e7dc2cfd022275.tar.gz cpython-93f562c4f9a751034616068468e7dc2cfd022275.tar.bz2 |
Merged revisions 77842 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk
........
r77842 | mark.dickinson | 2010-01-30 10:08:33 +0000 (Sat, 30 Jan 2010) | 4 lines
Issue #7767: Add new C-API function PyLong_AsLongLongAndOverflow, a
long long variant of PyLong_AsLongAndOverflow. Patch by Case Van
Horsen.
........
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/_testcapimodule.c | 167 |
1 files changed, 167 insertions, 0 deletions
diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 5671783..b635483 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -524,6 +524,171 @@ test_long_and_overflow(PyObject *self) return Py_None; } +/* Test the PyLong_AsLongLongAndOverflow API. General conversion to + PY_LONG_LONG is tested by test_long_api_inner. This test will + concentrate on proper handling of overflow. +*/ + +static PyObject * +test_long_long_and_overflow(PyObject *self) +{ + PyObject *num, *one, *temp; + PY_LONG_LONG value; + int overflow; + + /* Test that overflow is set properly for a large value. */ + /* num is a number larger than PY_LLONG_MAX on a typical machine. */ + num = PyLong_FromString("FFFFFFFFFFFFFFFFFFFFFFFF", NULL, 16); + if (num == NULL) + return NULL; + overflow = 1234; + value = PyLong_AsLongLongAndOverflow(num, &overflow); + Py_DECREF(num); + if (value == -1 && PyErr_Occurred()) + return NULL; + if (value != -1) + return raiseTestError("test_long_long_and_overflow", + "return value was not set to -1"); + if (overflow != 1) + return raiseTestError("test_long_long_and_overflow", + "overflow was not set to 1"); + + /* Same again, with num = PY_LLONG_MAX + 1 */ + num = PyLong_FromLongLong(PY_LLONG_MAX); + if (num == NULL) + return NULL; + one = PyLong_FromLong(1L); + if (one == NULL) { + Py_DECREF(num); + return NULL; + } + temp = PyNumber_Add(num, one); + Py_DECREF(one); + Py_DECREF(num); + num = temp; + if (num == NULL) + return NULL; + overflow = 0; + value = PyLong_AsLongLongAndOverflow(num, &overflow); + Py_DECREF(num); + if (value == -1 && PyErr_Occurred()) + return NULL; + if (value != -1) + return raiseTestError("test_long_long_and_overflow", + "return value was not set to -1"); + if (overflow != 1) + return raiseTestError("test_long_long_and_overflow", + "overflow was not set to 1"); + + /* Test that overflow is set properly for a large negative value. */ + /* num is a number smaller than PY_LLONG_MIN on a typical platform */ + num = PyLong_FromString("-FFFFFFFFFFFFFFFFFFFFFFFF", NULL, 16); + if (num == NULL) + return NULL; + overflow = 1234; + value = PyLong_AsLongLongAndOverflow(num, &overflow); + Py_DECREF(num); + if (value == -1 && PyErr_Occurred()) + return NULL; + if (value != -1) + return raiseTestError("test_long_long_and_overflow", + "return value was not set to -1"); + if (overflow != -1) + return raiseTestError("test_long_long_and_overflow", + "overflow was not set to -1"); + + /* Same again, with num = PY_LLONG_MIN - 1 */ + num = PyLong_FromLongLong(PY_LLONG_MIN); + if (num == NULL) + return NULL; + one = PyLong_FromLong(1L); + if (one == NULL) { + Py_DECREF(num); + return NULL; + } + temp = PyNumber_Subtract(num, one); + Py_DECREF(one); + Py_DECREF(num); + num = temp; + if (num == NULL) + return NULL; + overflow = 0; + value = PyLong_AsLongLongAndOverflow(num, &overflow); + Py_DECREF(num); + if (value == -1 && PyErr_Occurred()) + return NULL; + if (value != -1) + return raiseTestError("test_long_long_and_overflow", + "return value was not set to -1"); + if (overflow != -1) + return raiseTestError("test_long_long_and_overflow", + "overflow was not set to -1"); + + /* Test that overflow is cleared properly for small values. */ + num = PyLong_FromString("FF", NULL, 16); + if (num == NULL) + return NULL; + overflow = 1234; + value = PyLong_AsLongLongAndOverflow(num, &overflow); + Py_DECREF(num); + if (value == -1 && PyErr_Occurred()) + return NULL; + if (value != 0xFF) + return raiseTestError("test_long_long_and_overflow", + "expected return value 0xFF"); + if (overflow != 0) + return raiseTestError("test_long_long_and_overflow", + "overflow was not cleared"); + + num = PyLong_FromString("-FF", NULL, 16); + if (num == NULL) + return NULL; + overflow = 0; + value = PyLong_AsLongLongAndOverflow(num, &overflow); + Py_DECREF(num); + if (value == -1 && PyErr_Occurred()) + return NULL; + if (value != -0xFF) + return raiseTestError("test_long_long_and_overflow", + "expected return value 0xFF"); + if (overflow != 0) + return raiseTestError("test_long_long_and_overflow", + "overflow was set incorrectly"); + + num = PyLong_FromLongLong(PY_LLONG_MAX); + if (num == NULL) + return NULL; + overflow = 1234; + value = PyLong_AsLongLongAndOverflow(num, &overflow); + Py_DECREF(num); + if (value == -1 && PyErr_Occurred()) + return NULL; + if (value != PY_LLONG_MAX) + return raiseTestError("test_long_long_and_overflow", + "expected return value PY_LLONG_MAX"); + if (overflow != 0) + return raiseTestError("test_long_long_and_overflow", + "overflow was not cleared"); + + num = PyLong_FromLongLong(PY_LLONG_MIN); + if (num == NULL) + return NULL; + overflow = 0; + value = PyLong_AsLongLongAndOverflow(num, &overflow); + Py_DECREF(num); + if (value == -1 && PyErr_Occurred()) + return NULL; + if (value != PY_LLONG_MIN) + return raiseTestError("test_long_long_and_overflow", + "expected return value PY_LLONG_MIN"); + if (overflow != 0) + return raiseTestError("test_long_long_and_overflow", + "overflow was not cleared"); + + Py_INCREF(Py_None); + return Py_None; +} + /* 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 it fails. @@ -1791,6 +1956,8 @@ static PyMethodDef TestMethods[] = { {"getargs_L", getargs_L, METH_VARARGS}, {"getargs_K", getargs_K, METH_VARARGS}, {"test_longlong_api", test_longlong_api, METH_NOARGS}, + {"test_long_long_and_overflow", + (PyCFunction)test_long_long_and_overflow, METH_NOARGS}, {"test_L_code", (PyCFunction)test_L_code, METH_NOARGS}, {"codec_incrementalencoder", (PyCFunction)codec_incrementalencoder, METH_VARARGS}, |