This commit was manufactured by cvs2svn to create tag 'r23a1-fork'.
[python/dscho.git] / Modules / _testcapimodule.c
blob2054c805ac2bad23f81c5dc75e3661fa2f70994c
1 /*
2 * C Extension module to test Python interpreter C APIs.
4 * The 'test_*' functions exported by this module are run as part of the
5 * standard Python regression test, via Lib/test/test_capi.py.
6 */
8 #include "Python.h"
10 static PyObject *TestError; /* set to exception object in init */
12 /* Raise TestError with test_name + ": " + msg, and return NULL. */
14 static PyObject *
15 raiseTestError(const char* test_name, const char* msg)
17 char buf[2048];
19 if (strlen(test_name) + strlen(msg) > sizeof(buf) - 50)
20 PyErr_SetString(TestError, "internal error msg too large");
21 else {
22 PyOS_snprintf(buf, sizeof(buf), "%s: %s", test_name, msg);
23 PyErr_SetString(TestError, buf);
25 return NULL;
28 /* Test #defines from pyconfig.h (particularly the SIZEOF_* defines).
30 The ones derived from autoconf on the UNIX-like OSes can be relied
31 upon (in the absence of sloppy cross-compiling), but the Windows
32 platforms have these hardcoded. Better safe than sorry.
34 static PyObject*
35 sizeof_error(const char* fatname, const char* typename,
36 int expected, int got)
38 char buf[1024];
39 PyOS_snprintf(buf, sizeof(buf),
40 "%.200s #define == %d but sizeof(%.200s) == %d",
41 fatname, expected, typename, got);
42 PyErr_SetString(TestError, buf);
43 return (PyObject*)NULL;
46 static PyObject*
47 test_config(PyObject *self)
49 #define CHECK_SIZEOF(FATNAME, TYPE) \
50 if (FATNAME != sizeof(TYPE)) \
51 return sizeof_error(#FATNAME, #TYPE, FATNAME, sizeof(TYPE))
53 CHECK_SIZEOF(SIZEOF_SHORT, short);
54 CHECK_SIZEOF(SIZEOF_INT, int);
55 CHECK_SIZEOF(SIZEOF_LONG, long);
56 CHECK_SIZEOF(SIZEOF_VOID_P, void*);
57 CHECK_SIZEOF(SIZEOF_TIME_T, time_t);
58 #ifdef HAVE_LONG_LONG
59 CHECK_SIZEOF(SIZEOF_LONG_LONG, LONG_LONG);
60 #endif
62 #undef CHECK_SIZEOF
64 Py_INCREF(Py_None);
65 return Py_None;
68 static PyObject*
69 test_list_api(PyObject *self)
71 PyObject* list;
72 int i;
74 /* SF bug 132008: PyList_Reverse segfaults */
75 #define NLIST 30
76 list = PyList_New(NLIST);
77 if (list == (PyObject*)NULL)
78 return (PyObject*)NULL;
79 /* list = range(NLIST) */
80 for (i = 0; i < NLIST; ++i) {
81 PyObject* anint = PyInt_FromLong(i);
82 if (anint == (PyObject*)NULL) {
83 Py_DECREF(list);
84 return (PyObject*)NULL;
86 PyList_SET_ITEM(list, i, anint);
88 /* list.reverse(), via PyList_Reverse() */
89 i = PyList_Reverse(list); /* should not blow up! */
90 if (i != 0) {
91 Py_DECREF(list);
92 return (PyObject*)NULL;
94 /* Check that list == range(29, -1, -1) now */
95 for (i = 0; i < NLIST; ++i) {
96 PyObject* anint = PyList_GET_ITEM(list, i);
97 if (PyInt_AS_LONG(anint) != NLIST-1-i) {
98 PyErr_SetString(TestError,
99 "test_list_api: reverse screwed up");
100 Py_DECREF(list);
101 return (PyObject*)NULL;
104 Py_DECREF(list);
105 #undef NLIST
107 Py_INCREF(Py_None);
108 return Py_None;
111 static int
112 test_dict_inner(int count)
114 int pos = 0, iterations = 0, i;
115 PyObject *dict = PyDict_New();
116 PyObject *v, *k;
118 if (dict == NULL)
119 return -1;
121 for (i = 0; i < count; i++) {
122 v = PyInt_FromLong(i);
123 PyDict_SetItem(dict, v, v);
124 Py_DECREF(v);
127 while (PyDict_Next(dict, &pos, &k, &v)) {
128 PyObject *o;
129 iterations++;
131 i = PyInt_AS_LONG(v) + 1;
132 o = PyInt_FromLong(i);
133 if (o == NULL)
134 return -1;
135 if (PyDict_SetItem(dict, k, o) < 0) {
136 Py_DECREF(o);
137 return -1;
139 Py_DECREF(o);
142 Py_DECREF(dict);
144 if (iterations != count) {
145 PyErr_SetString(
146 TestError,
147 "test_dict_iteration: dict iteration went wrong ");
148 return -1;
149 } else {
150 return 0;
154 static PyObject*
155 test_dict_iteration(PyObject* self)
157 int i;
159 for (i = 0; i < 200; i++) {
160 if (test_dict_inner(i) < 0) {
161 return NULL;
165 Py_INCREF(Py_None);
166 return Py_None;
170 /* Tests of PyLong_{As, From}{Unsigned,}Long(), and (#ifdef HAVE_LONG_LONG)
171 PyLong_{As, From}{Unsigned,}LongLong().
173 Note that the meat of the test is contained in testcapi_long.h.
174 This is revolting, but delicate code duplication is worse: "almost
175 exactly the same" code is needed to test LONG_LONG, but the ubiquitous
176 dependence on type names makes it impossible to use a parameterized
177 function. A giant macro would be even worse than this. A C++ template
178 would be perfect.
180 The "report an error" functions are deliberately not part of the #include
181 file: if the test fails, you can set a breakpoint in the appropriate
182 error function directly, and crawl back from there in the debugger.
185 #define UNBIND(X) Py_DECREF(X); (X) = NULL
187 static PyObject *
188 raise_test_long_error(const char* msg)
190 return raiseTestError("test_long_api", msg);
193 #define TESTNAME test_long_api_inner
194 #define TYPENAME long
195 #define F_S_TO_PY PyLong_FromLong
196 #define F_PY_TO_S PyLong_AsLong
197 #define F_U_TO_PY PyLong_FromUnsignedLong
198 #define F_PY_TO_U PyLong_AsUnsignedLong
200 #include "testcapi_long.h"
202 static PyObject *
203 test_long_api(PyObject* self)
205 return TESTNAME(raise_test_long_error);
208 #undef TESTNAME
209 #undef TYPENAME
210 #undef F_S_TO_PY
211 #undef F_PY_TO_S
212 #undef F_U_TO_PY
213 #undef F_PY_TO_U
215 #ifdef HAVE_LONG_LONG
217 static PyObject *
218 raise_test_longlong_error(const char* msg)
220 return raiseTestError("test_longlong_api", msg);
223 #define TESTNAME test_longlong_api_inner
224 #define TYPENAME LONG_LONG
225 #define F_S_TO_PY PyLong_FromLongLong
226 #define F_PY_TO_S PyLong_AsLongLong
227 #define F_U_TO_PY PyLong_FromUnsignedLongLong
228 #define F_PY_TO_U PyLong_AsUnsignedLongLong
230 #include "testcapi_long.h"
232 static PyObject *
233 test_longlong_api(PyObject* self)
235 return TESTNAME(raise_test_longlong_error);
238 #undef TESTNAME
239 #undef TYPENAME
240 #undef F_S_TO_PY
241 #undef F_PY_TO_S
242 #undef F_U_TO_PY
243 #undef F_PY_TO_U
245 /* Test the L code for PyArg_ParseTuple. This should deliver a LONG_LONG
246 for both long and int arguments. The test may leak a little memory if
247 it fails.
249 static PyObject *
250 test_L_code(PyObject *self)
252 PyObject *tuple, *num;
253 LONG_LONG value;
255 tuple = PyTuple_New(1);
256 if (tuple == NULL)
257 return NULL;
259 num = PyLong_FromLong(42);
260 if (num == NULL)
261 return NULL;
263 PyTuple_SET_ITEM(tuple, 0, num);
265 value = -1;
266 if (PyArg_ParseTuple(tuple, "L:test_L_code", &value) < 0)
267 return NULL;
268 if (value != 42)
269 return raiseTestError("test_L_code",
270 "L code returned wrong value for long 42");
272 Py_DECREF(num);
273 num = PyInt_FromLong(42);
274 if (num == NULL)
275 return NULL;
277 PyTuple_SET_ITEM(tuple, 0, num);
279 value = -1;
280 if (PyArg_ParseTuple(tuple, "L:test_L_code", &value) < 0)
281 return NULL;
282 if (value != 42)
283 return raiseTestError("test_L_code",
284 "L code returned wrong value for int 42");
286 Py_DECREF(tuple);
287 Py_INCREF(Py_None);
288 return Py_None;
291 #endif /* ifdef HAVE_LONG_LONG */
293 #ifdef Py_USING_UNICODE
295 /* Test the u and u# codes for PyArg_ParseTuple. May leak memory in case
296 of an error.
298 static PyObject *
299 test_u_code(PyObject *self)
301 PyObject *tuple, *obj;
302 Py_UNICODE *value;
303 int len;
305 tuple = PyTuple_New(1);
306 if (tuple == NULL)
307 return NULL;
309 obj = PyUnicode_Decode("test", strlen("test"),
310 "ascii", NULL);
311 if (obj == NULL)
312 return NULL;
314 PyTuple_SET_ITEM(tuple, 0, obj);
316 value = 0;
317 if (PyArg_ParseTuple(tuple, "u:test_u_code", &value) < 0)
318 return NULL;
319 if (value != PyUnicode_AS_UNICODE(obj))
320 return raiseTestError("test_u_code",
321 "u code returned wrong value for u'test'");
322 value = 0;
323 if (PyArg_ParseTuple(tuple, "u#:test_u_code", &value, &len) < 0)
324 return NULL;
325 if (value != PyUnicode_AS_UNICODE(obj) ||
326 len != PyUnicode_GET_SIZE(obj))
327 return raiseTestError("test_u_code",
328 "u# code returned wrong values for u'test'");
330 Py_DECREF(tuple);
331 Py_INCREF(Py_None);
332 return Py_None;
335 #endif
337 static PyObject *
338 raise_exception(PyObject *self, PyObject *args)
340 PyObject *exc;
341 PyObject *exc_args, *v;
342 int num_args, i;
344 if (!PyArg_ParseTuple(args, "Oi:raise_exception",
345 &exc, &num_args))
346 return NULL;
348 exc_args = PyTuple_New(num_args);
349 if (exc_args == NULL)
350 return NULL;
351 for (i = 0; i < num_args; ++i) {
352 v = PyInt_FromLong(i);
353 if (v == NULL) {
354 Py_DECREF(exc_args);
355 return NULL;
357 PyTuple_SET_ITEM(exc_args, i, v);
359 PyErr_SetObject(exc, exc_args);
360 return NULL;
363 static PyMethodDef TestMethods[] = {
364 {"raise_exception", raise_exception, METH_VARARGS},
365 {"test_config", (PyCFunction)test_config, METH_NOARGS},
366 {"test_list_api", (PyCFunction)test_list_api, METH_NOARGS},
367 {"test_dict_iteration", (PyCFunction)test_dict_iteration,METH_NOARGS},
368 {"test_long_api", (PyCFunction)test_long_api, METH_NOARGS},
369 #ifdef HAVE_LONG_LONG
370 {"test_longlong_api", (PyCFunction)test_longlong_api, METH_NOARGS},
371 {"test_L_code", (PyCFunction)test_L_code, METH_NOARGS},
372 #endif
373 #ifdef Py_USING_UNICODE
374 {"test_u_code", (PyCFunction)test_u_code, METH_NOARGS},
375 #endif
376 {NULL, NULL} /* sentinel */
379 PyMODINIT_FUNC
380 init_testcapi(void)
382 PyObject *m;
384 m = Py_InitModule("_testcapi", TestMethods);
386 TestError = PyErr_NewException("_testcapi.error", NULL, NULL);
387 Py_INCREF(TestError);
388 PyModule_AddObject(m, "error", TestError);