[Python-checkins] CVS: python/dist/src/Modules _testcapimodule.c,1.4,1.5
Tim Peters
tim_one@users.sourceforge.net
Tue, 12 Jun 2001 17:36:00 -0700
Update of /cvsroot/python/python/dist/src/Modules
In directory usw-pr-cvs1:/tmp/cvs-serv10010/python/dist/src/Modules
Modified Files:
_testcapimodule.c
Log Message:
longobject.c:
Replaced PyLong_{As,From}{Unsigned,}LongLong guts with calls
to _PyLong_{As,From}ByteArray.
_testcapimodule.c:
Added strong tests of PyLong_{As,From}{Unsigned,}LongLong.
Fixes SF bug #432552 PyLong_AsLongLong() problems.
Possible bugfix candidate, but the fix relies on code added to longobject
to support the new q/Q structmodule format codes.
Index: _testcapimodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/_testcapimodule.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -r1.4 -r1.5
*** _testcapimodule.c 2001/06/12 20:10:01 1.4
--- _testcapimodule.c 2001/06/13 00:35:57 1.5
***************
*** 178,203 ****
static PyObject *
test_longlong_api(PyObject* self, PyObject* args)
{
! /* unsigned LONG_LONG uinput, uoutput; */
! LONG_LONG input, output;
PyObject *pyresult;
if (!PyArg_ParseTuple(args, ":test_longlong_api"))
return NULL;
! input = 0;
! pyresult = PyLong_FromLongLong(input);
! if (pyresult == NULL)
! return raiseTestError("test_longlong_api",
! "unexpected null result");
! output = PyLong_AsLongLong(pyresult);
! if (output == (LONG_LONG)-1 && PyErr_Occurred())
! return raiseTestError("test_longlong_api",
! "unexpected -1 result");
! if (output != input)
! return raiseTestError("test_longlong_api",
! "output != input");
! Py_DECREF(pyresult);
Py_INCREF(Py_None);
--- 178,346 ----
static PyObject *
+ raise_test_longlong_error(const char* msg)
+ {
+ return raiseTestError("test_longlong_api", msg);
+ }
+
+ #define UNBIND(X) Py_DECREF(X); (X) = NULL
+
+ static PyObject *
test_longlong_api(PyObject* self, PyObject* args)
{
! const int NBITS = SIZEOF_LONG_LONG * 8;
! unsigned LONG_LONG base;
PyObject *pyresult;
+ int i;
if (!PyArg_ParseTuple(args, ":test_longlong_api"))
return NULL;
+
+
+ /* Note: This test lets PyObjects leak if an error is raised. Since
+ an error should never be raised, leaks are impossible <wink>. */
+
+ /* Test native -> PyLong -> native roundtrip identity.
+ * Generate all powers of 2, and test them and their negations,
+ * plus the numbers +-1 off from them.
+ */
+ base = 1;
+ for (i = 0;
+ i < NBITS + 1; /* on last, base overflows to 0 */
+ ++i, base <<= 1)
+ {
+ int j;
+ for (j = 0; j < 6; ++j) {
+ LONG_LONG in, out;
+ unsigned LONG_LONG uin, uout;
+
+ /* For 0, 1, 2 use base; for 3, 4, 5 use -base */
+ uin = j < 3 ? base
+ : (unsigned LONG_LONG)(-(LONG_LONG)base);
+
+ /* For 0 & 3, subtract 1.
+ * For 1 & 4, leave alone.
+ * For 2 & 5, add 1.
+ */
+ uin += (unsigned LONG_LONG)(LONG_LONG)(j % 3 - 1);
+
+ pyresult = PyLong_FromUnsignedLongLong(uin);
+ if (pyresult == NULL)
+ return raise_test_longlong_error(
+ "unsigned unexpected null result");
+
+ uout = PyLong_AsUnsignedLongLong(pyresult);
+ if (uout == (unsigned LONG_LONG)-1 && PyErr_Occurred())
+ return raise_test_longlong_error(
+ "unsigned unexpected -1 result");
+ if (uout != uin)
+ return raise_test_longlong_error(
+ "unsigned output != input");
+ UNBIND(pyresult);
+
+ in = (LONG_LONG)uin;
+ pyresult = PyLong_FromLongLong(in);
+ if (pyresult == NULL)
+ return raise_test_longlong_error(
+ "signed unexpected null result");
+
+ out = PyLong_AsLongLong(pyresult);
+ if (out == (LONG_LONG)-1 && PyErr_Occurred())
+ return raise_test_longlong_error(
+ "signed unexpected -1 result");
+ if (out != in)
+ return raise_test_longlong_error(
+ "signed output != input");
+ UNBIND(pyresult);
+ }
+ }
+
+ /* Overflow tests. The loop above ensured that all limit cases that
+ * should not overflow don't overflow, so all we need to do here is
+ * provoke one-over-the-limit cases (not exhaustive, but sharp).
+ */
+ {
+ PyObject *one, *x, *y;
+ LONG_LONG out;
+ unsigned LONG_LONG uout;
+
+ one = PyLong_FromLong(1);
+ if (one == NULL)
+ return raise_test_longlong_error(
+ "unexpected NULL from PyLong_FromLong");
+
+ /* Unsigned complains about -1? */
+ x = PyNumber_Negative(one);
+ if (x == NULL)
+ return raise_test_longlong_error(
+ "unexpected NULL from PyNumber_Negative");
+
+ uout = PyLong_AsUnsignedLongLong(x);
+ if (uout != (unsigned LONG_LONG)-1 || !PyErr_Occurred())
+ return raise_test_longlong_error(
+ "PyLong_AsUnsignedLongLong(-1) didn't "
+ "complain");
+ PyErr_Clear();
+ UNBIND(x);
+
+ /* Unsigned complains about 2**NBITS? */
+ y = PyLong_FromLong((long)NBITS);
+ if (y == NULL)
+ return raise_test_longlong_error(
+ "unexpected NULL from PyLong_FromLong");
+
+ x = PyNumber_Lshift(one, y); /* 1L << NBITS, == 2**NBITS */
+ UNBIND(y);
+ if (x == NULL)
+ return raise_test_longlong_error(
+ "unexpected NULL from PyNumber_Lshift");
+
+ uout = PyLong_AsUnsignedLongLong(x);
+ if (uout != (unsigned LONG_LONG)-1 || !PyErr_Occurred())
+ return raise_test_longlong_error(
+ "PyLong_AsUnsignedLongLong(2**NBITS) didn't "
+ "complain");
+ PyErr_Clear();
+
+ /* Signed complains about 2**(NBITS-1)?
+ x still has 2**NBITS. */
+ y = PyNumber_Rshift(x, one); /* 2**(NBITS-1) */
+ UNBIND(x);
+ if (y == NULL)
+ return raise_test_longlong_error(
+ "unexpected NULL from PyNumber_Rshift");
+
+ out = PyLong_AsLongLong(y);
+ if (out != (LONG_LONG)-1 || !PyErr_Occurred())
+ return raise_test_longlong_error(
+ "PyLong_AsLongLong(2**(NBITS-1)) didn't "
+ "complain");
+ PyErr_Clear();
+
+ /* Signed complains about -2**(NBITS-1)-1?;
+ y still has 2**(NBITS-1). */
+ x = PyNumber_Negative(y); /* -(2**(NBITS-1)) */
+ UNBIND(y);
+ if (x == NULL)
+ return raise_test_longlong_error(
+ "unexpected NULL from PyNumber_Negative");
+
+ y = PyNumber_Subtract(x, one); /* -(2**(NBITS-1))-1 */
+ UNBIND(x);
+ if (y == NULL)
+ return raise_test_longlong_error(
+ "unexpected NULL from PyNumber_Subtract");
+
+ out = PyLong_AsLongLong(y);
+ if (out != (LONG_LONG)-1 || !PyErr_Occurred())
+ return raise_test_longlong_error(
+ "PyLong_AsLongLong(-2**(NBITS-1)-1) didn't "
+ "complain");
+ PyErr_Clear();
+ UNBIND(y);
! Py_XDECREF(x);
! Py_XDECREF(y);
! Py_DECREF(one);
! }
Py_INCREF(Py_None);