1
1
/* Poor-man's template. Macros used:
2
TESTNAME name of the test (like test_long_api_inner)
3
TYPENAME the signed type (like long)
4
F_S_TO_PY convert signed to pylong; TYPENAME -> PyObject*
5
F_PY_TO_S convert pylong to signed; PyObject* -> TYPENAME
6
F_U_TO_PY convert unsigned to pylong; unsigned TYPENAME -> PyObject*
2
TESTNAME name of the test (like test_long_api_inner)
3
TYPENAME the signed type (like long)
4
F_S_TO_PY convert signed to pylong; TYPENAME -> PyObject*
5
F_PY_TO_S convert pylong to signed; PyObject* -> TYPENAME
6
F_U_TO_PY convert unsigned to pylong; unsigned TYPENAME -> PyObject*
7
7
F_PY_TO_U convert pylong to unsigned; PyObject* -> unsigned TYPENAME
11
11
TESTNAME(PyObject *error(const char*))
13
const int NBITS = sizeof(TYPENAME) * 8;
14
unsigned TYPENAME base;
18
/* Note: This test lets PyObjects leak if an error is raised. Since
19
an error should never be raised, leaks are impossible <wink>. */
21
/* Test native -> PyLong -> native roundtrip identity.
22
* Generate all powers of 2, and test them and their negations,
23
* plus the numbers +-1 off from them.
27
i < NBITS + 1; /* on last, base overflows to 0 */
31
for (j = 0; j < 6; ++j) {
33
unsigned TYPENAME uin, uout;
35
/* For 0, 1, 2 use base; for 3, 4, 5 use -base */
37
: (unsigned TYPENAME)(-(TYPENAME)base);
39
/* For 0 & 3, subtract 1.
40
* For 1 & 4, leave alone.
43
uin += (unsigned TYPENAME)(TYPENAME)(j % 3 - 1);
45
pyresult = F_U_TO_PY(uin);
48
"unsigned unexpected null result");
50
uout = F_PY_TO_U(pyresult);
51
if (uout == (unsigned TYPENAME)-1 && PyErr_Occurred())
53
"unsigned unexpected -1 result");
56
"unsigned output != input");
60
pyresult = F_S_TO_PY(in);
63
"signed unexpected null result");
65
out = F_PY_TO_S(pyresult);
66
if (out == (TYPENAME)-1 && PyErr_Occurred())
68
"signed unexpected -1 result");
71
"signed output != input");
76
/* Overflow tests. The loop above ensured that all limit cases that
77
* should not overflow don't overflow, so all we need to do here is
78
* provoke one-over-the-limit cases (not exhaustive, but sharp).
81
PyObject *one, *x, *y;
83
unsigned TYPENAME uout;
85
one = PyLong_FromLong(1);
88
"unexpected NULL from PyLong_FromLong");
90
/* Unsigned complains about -1? */
91
x = PyNumber_Negative(one);
94
"unexpected NULL from PyNumber_Negative");
97
if (uout != (unsigned TYPENAME)-1 || !PyErr_Occurred())
99
"PyLong_AsUnsignedXXX(-1) didn't complain");
100
if (!PyErr_ExceptionMatches(PyExc_OverflowError))
102
"PyLong_AsUnsignedXXX(-1) raised "
103
"something other than OverflowError");
107
/* Unsigned complains about 2**NBITS? */
108
y = PyLong_FromLong((long)NBITS);
111
"unexpected NULL from PyLong_FromLong");
113
x = PyNumber_Lshift(one, y); /* 1L << NBITS, == 2**NBITS */
117
"unexpected NULL from PyNumber_Lshift");
120
if (uout != (unsigned TYPENAME)-1 || !PyErr_Occurred())
122
"PyLong_AsUnsignedXXX(2**NBITS) didn't "
124
if (!PyErr_ExceptionMatches(PyExc_OverflowError))
126
"PyLong_AsUnsignedXXX(2**NBITS) raised "
127
"something other than OverflowError");
130
/* Signed complains about 2**(NBITS-1)?
131
x still has 2**NBITS. */
132
y = PyNumber_Rshift(x, one); /* 2**(NBITS-1) */
136
"unexpected NULL from PyNumber_Rshift");
139
if (out != (TYPENAME)-1 || !PyErr_Occurred())
141
"PyLong_AsXXX(2**(NBITS-1)) didn't "
143
if (!PyErr_ExceptionMatches(PyExc_OverflowError))
145
"PyLong_AsXXX(2**(NBITS-1)) raised "
146
"something other than OverflowError");
149
/* Signed complains about -2**(NBITS-1)-1?;
150
y still has 2**(NBITS-1). */
151
x = PyNumber_Negative(y); /* -(2**(NBITS-1)) */
155
"unexpected NULL from PyNumber_Negative");
157
y = PyNumber_Subtract(x, one); /* -(2**(NBITS-1))-1 */
161
"unexpected NULL from PyNumber_Subtract");
164
if (out != (TYPENAME)-1 || !PyErr_Occurred())
166
"PyLong_AsXXX(-2**(NBITS-1)-1) didn't "
168
if (!PyErr_ExceptionMatches(PyExc_OverflowError))
170
"PyLong_AsXXX(-2**(NBITS-1)-1) raised "
171
"something other than OverflowError");
13
const int NBITS = sizeof(TYPENAME) * 8;
14
unsigned TYPENAME base;
18
/* Note: This test lets PyObjects leak if an error is raised. Since
19
an error should never be raised, leaks are impossible <wink>. */
21
/* Test native -> PyLong -> native roundtrip identity.
22
* Generate all powers of 2, and test them and their negations,
23
* plus the numbers +-1 off from them.
27
i < NBITS + 1; /* on last, base overflows to 0 */
31
for (j = 0; j < 6; ++j) {
33
unsigned TYPENAME uin, uout;
35
/* For 0, 1, 2 use base; for 3, 4, 5 use -base */
37
: (unsigned TYPENAME)(-(TYPENAME)base);
39
/* For 0 & 3, subtract 1.
40
* For 1 & 4, leave alone.
43
uin += (unsigned TYPENAME)(TYPENAME)(j % 3 - 1);
45
pyresult = F_U_TO_PY(uin);
48
"unsigned unexpected null result");
50
uout = F_PY_TO_U(pyresult);
51
if (uout == (unsigned TYPENAME)-1 && PyErr_Occurred())
53
"unsigned unexpected -1 result");
56
"unsigned output != input");
60
pyresult = F_S_TO_PY(in);
63
"signed unexpected null result");
65
out = F_PY_TO_S(pyresult);
66
if (out == (TYPENAME)-1 && PyErr_Occurred())
68
"signed unexpected -1 result");
71
"signed output != input");
76
/* Overflow tests. The loop above ensured that all limit cases that
77
* should not overflow don't overflow, so all we need to do here is
78
* provoke one-over-the-limit cases (not exhaustive, but sharp).
81
PyObject *one, *x, *y;
83
unsigned TYPENAME uout;
85
one = PyLong_FromLong(1);
88
"unexpected NULL from PyLong_FromLong");
90
/* Unsigned complains about -1? */
91
x = PyNumber_Negative(one);
94
"unexpected NULL from PyNumber_Negative");
97
if (uout != (unsigned TYPENAME)-1 || !PyErr_Occurred())
99
"PyLong_AsUnsignedXXX(-1) didn't complain");
100
if (!PyErr_ExceptionMatches(PyExc_OverflowError))
102
"PyLong_AsUnsignedXXX(-1) raised "
103
"something other than OverflowError");
107
/* Unsigned complains about 2**NBITS? */
108
y = PyLong_FromLong((long)NBITS);
111
"unexpected NULL from PyLong_FromLong");
113
x = PyNumber_Lshift(one, y); /* 1L << NBITS, == 2**NBITS */
117
"unexpected NULL from PyNumber_Lshift");
120
if (uout != (unsigned TYPENAME)-1 || !PyErr_Occurred())
122
"PyLong_AsUnsignedXXX(2**NBITS) didn't "
124
if (!PyErr_ExceptionMatches(PyExc_OverflowError))
126
"PyLong_AsUnsignedXXX(2**NBITS) raised "
127
"something other than OverflowError");
130
/* Signed complains about 2**(NBITS-1)?
131
x still has 2**NBITS. */
132
y = PyNumber_Rshift(x, one); /* 2**(NBITS-1) */
136
"unexpected NULL from PyNumber_Rshift");
139
if (out != (TYPENAME)-1 || !PyErr_Occurred())
141
"PyLong_AsXXX(2**(NBITS-1)) didn't "
143
if (!PyErr_ExceptionMatches(PyExc_OverflowError))
145
"PyLong_AsXXX(2**(NBITS-1)) raised "
146
"something other than OverflowError");
149
/* Signed complains about -2**(NBITS-1)-1?;
150
y still has 2**(NBITS-1). */
151
x = PyNumber_Negative(y); /* -(2**(NBITS-1)) */
155
"unexpected NULL from PyNumber_Negative");
157
y = PyNumber_Subtract(x, one); /* -(2**(NBITS-1))-1 */
161
"unexpected NULL from PyNumber_Subtract");
164
if (out != (TYPENAME)-1 || !PyErr_Occurred())
166
"PyLong_AsXXX(-2**(NBITS-1)-1) didn't "
168
if (!PyErr_ExceptionMatches(PyExc_OverflowError))
170
"PyLong_AsXXX(-2**(NBITS-1)-1) raised "
171
"something other than OverflowError");