summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorMark Dickinson <dickinsm@gmail.com>2010-01-30 10:30:15 (GMT)
committerMark Dickinson <dickinsm@gmail.com>2010-01-30 10:30:15 (GMT)
commit93f562c4f9a751034616068468e7dc2cfd022275 (patch)
tree5f41dda113e687676341b3032abc0545c5c4543e /Modules
parenta79b75743af3d7c66fcccc1c47699c838422064b (diff)
downloadcpython-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.c167
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},