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*
7 F_PY_TO_U convert pylong to unsigned; PyObject* -> unsigned TYPENAME
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");