blob: 1c5b0e5aa665d3449a9f40b425a82de79a220a58 [file] [log] [blame]
Tim Peters9ea17ac2001-02-02 05:57:15 +00001/*
2 * C Extension module to test Python interpreter C APIs.
3 *
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 */
7
8#include "Python.h"
9
10static PyObject *TestError; /* set to exception object in init */
11
Tim Peters91621db2001-06-12 20:10:01 +000012/* Raise TestError with test_name + ": " + msg, and return NULL. */
13
14static PyObject *
15raiseTestError(const char* test_name, const char* msg)
16{
17 char buf[2048];
18
19 if (strlen(test_name) + strlen(msg) > sizeof(buf) - 50)
20 PyErr_SetString(TestError, "internal error msg too large");
21 else {
22 sprintf(buf, "%s: %s", test_name, msg);
23 PyErr_SetString(TestError, buf);
24 }
25 return NULL;
26}
27
Tim Peters9ea17ac2001-02-02 05:57:15 +000028/* Test #defines from config.h (particularly the SIZEOF_* defines).
29
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.
33*/
34static PyObject*
35sizeof_error(const char* fatname, const char* typename,
36 int expected, int got)
37{
38 char buf[1024];
39 sprintf(buf, "%s #define == %d but sizeof(%s) == %d",
40 fatname, expected, typename, got);
41 PyErr_SetString(TestError, buf);
42 return (PyObject*)NULL;
43}
44
45static PyObject*
46test_config(PyObject *self, PyObject *args)
47{
48 if (!PyArg_ParseTuple(args, ":test_config"))
49 return NULL;
50
51#define CHECK_SIZEOF(FATNAME, TYPE) \
52 if (FATNAME != sizeof(TYPE)) \
53 return sizeof_error(#FATNAME, #TYPE, FATNAME, sizeof(TYPE))
54
55 CHECK_SIZEOF(SIZEOF_INT, int);
56 CHECK_SIZEOF(SIZEOF_LONG, long);
57 CHECK_SIZEOF(SIZEOF_VOID_P, void*);
58 CHECK_SIZEOF(SIZEOF_TIME_T, time_t);
59#ifdef HAVE_LONG_LONG
60 CHECK_SIZEOF(SIZEOF_LONG_LONG, LONG_LONG);
61#endif
62
63#undef CHECK_SIZEOF
64
65 Py_INCREF(Py_None);
66 return Py_None;
67}
68
Tim Peters5c4d5bf2001-02-12 22:13:26 +000069static PyObject*
70test_list_api(PyObject *self, PyObject *args)
71{
72 PyObject* list;
73 int i;
74 if (!PyArg_ParseTuple(args, ":test_list_api"))
75 return NULL;
76
77 /* SF bug 132008: PyList_Reverse segfaults */
78#define NLIST 30
79 list = PyList_New(NLIST);
80 if (list == (PyObject*)NULL)
81 return (PyObject*)NULL;
82 /* list = range(NLIST) */
83 for (i = 0; i < NLIST; ++i) {
84 PyObject* anint = PyInt_FromLong(i);
85 if (anint == (PyObject*)NULL) {
86 Py_DECREF(list);
87 return (PyObject*)NULL;
88 }
89 PyList_SET_ITEM(list, i, anint);
90 }
91 /* list.reverse(), via PyList_Reverse() */
92 i = PyList_Reverse(list); /* should not blow up! */
93 if (i != 0) {
94 Py_DECREF(list);
95 return (PyObject*)NULL;
96 }
97 /* Check that list == range(29, -1, -1) now */
98 for (i = 0; i < NLIST; ++i) {
99 PyObject* anint = PyList_GET_ITEM(list, i);
100 if (PyInt_AS_LONG(anint) != NLIST-1-i) {
101 PyErr_SetString(TestError,
102 "test_list_api: reverse screwed up");
103 Py_DECREF(list);
104 return (PyObject*)NULL;
105 }
106 }
107 Py_DECREF(list);
108#undef NLIST
109
110 Py_INCREF(Py_None);
111 return Py_None;
112}
113
Guido van Rossumeb0d9922001-04-13 17:08:15 +0000114static int
115test_dict_inner(int count)
116{
117 int pos = 0, iterations = 0, i;
118 PyObject *dict = PyDict_New();
119 PyObject *v, *k;
120
121 if (dict == NULL)
122 return -1;
123
124 for (i = 0; i < count; i++) {
125 v = PyInt_FromLong(i);
126 PyDict_SetItem(dict, v, v);
127 Py_DECREF(v);
128 }
129
130 while (PyDict_Next(dict, &pos, &k, &v)) {
131 PyObject *o;
132 iterations++;
133
134 i = PyInt_AS_LONG(v) + 1;
135 o = PyInt_FromLong(i);
136 if (o == NULL)
137 return -1;
138 if (PyDict_SetItem(dict, k, o) < 0) {
139 Py_DECREF(o);
140 return -1;
141 }
142 Py_DECREF(o);
143 }
144
145 Py_DECREF(dict);
146
147 if (iterations != count) {
148 PyErr_SetString(
149 TestError,
150 "test_dict_iteration: dict iteration went wrong ");
151 return -1;
152 } else {
153 return 0;
154 }
155}
156
157static PyObject*
158test_dict_iteration(PyObject* self, PyObject* args)
159{
160 int i;
161
162 if (!PyArg_ParseTuple(args, ":test_dict_iteration"))
163 return NULL;
Tim Peters91621db2001-06-12 20:10:01 +0000164
Guido van Rossumeb0d9922001-04-13 17:08:15 +0000165 for (i = 0; i < 200; i++) {
166 if (test_dict_inner(i) < 0) {
167 return NULL;
168 }
169 }
170
171 Py_INCREF(Py_None);
172 return Py_None;
173}
174
Tim Peters91621db2001-06-12 20:10:01 +0000175
Tim Peterse7c1f9b2001-06-14 00:55:41 +0000176/* Tests of PyLong_{As, From}{Unsigned,}Long(), and (#ifdef HAVE_LONG_LONG)
Tim Petersff70d3c2001-06-14 01:11:03 +0000177 PyLong_{As, From}{Unsigned,}LongLong().
Tim Peterse7c1f9b2001-06-14 00:55:41 +0000178
179 Note that the meat of the test is contained in testcapi_long.h.
180 This is revolting, but delicate code duplication is worse: "almost
181 exactly the same" code is needed to test LONG_LONG, but the ubiquitous
182 dependence on type names makes it impossible to use a parameterized
183 function. A giant macro would be even worse than this. A C++ template
184 would be perfect.
185
186 The "report an error" functions are deliberately not part of the #include
187 file: if the test fails, you can set a breakpoint in the appropriate
188 error function directly, and crawl back from there in the debugger.
189*/
190
191#define UNBIND(X) Py_DECREF(X); (X) = NULL
192
193static PyObject *
194raise_test_long_error(const char* msg)
195{
196 return raiseTestError("test_long_api", msg);
197}
198
199#define TESTNAME test_long_api_inner
200#define TYPENAME long
201#define F_S_TO_PY PyLong_FromLong
202#define F_PY_TO_S PyLong_AsLong
203#define F_U_TO_PY PyLong_FromUnsignedLong
204#define F_PY_TO_U PyLong_AsUnsignedLong
Tim Peterse7c1f9b2001-06-14 00:55:41 +0000205
206#include "testcapi_long.h"
207
208static PyObject *
209test_long_api(PyObject* self, PyObject* args)
210{
211 if (!PyArg_ParseTuple(args, ":test_long_api"))
212 return NULL;
213
Tim Peters83c9edc2001-06-16 08:10:13 +0000214 return TESTNAME(raise_test_long_error);
Tim Peterse7c1f9b2001-06-14 00:55:41 +0000215}
216
217#undef TESTNAME
218#undef TYPENAME
219#undef F_S_TO_PY
220#undef F_PY_TO_S
221#undef F_U_TO_PY
222#undef F_PY_TO_U
Tim Peterse7c1f9b2001-06-14 00:55:41 +0000223
224#ifdef HAVE_LONG_LONG
Tim Peters91621db2001-06-12 20:10:01 +0000225
226static PyObject *
Tim Petersd1a7da62001-06-13 00:35:57 +0000227raise_test_longlong_error(const char* msg)
228{
229 return raiseTestError("test_longlong_api", msg);
230}
231
Tim Peterse7c1f9b2001-06-14 00:55:41 +0000232#define TESTNAME test_longlong_api_inner
233#define TYPENAME LONG_LONG
234#define F_S_TO_PY PyLong_FromLongLong
235#define F_PY_TO_S PyLong_AsLongLong
236#define F_U_TO_PY PyLong_FromUnsignedLongLong
237#define F_PY_TO_U PyLong_AsUnsignedLongLong
Tim Peterse7c1f9b2001-06-14 00:55:41 +0000238
239#include "testcapi_long.h"
Tim Petersd1a7da62001-06-13 00:35:57 +0000240
241static PyObject *
Tim Peters91621db2001-06-12 20:10:01 +0000242test_longlong_api(PyObject* self, PyObject* args)
243{
Tim Peters91621db2001-06-12 20:10:01 +0000244 if (!PyArg_ParseTuple(args, ":test_longlong_api"))
245 return NULL;
246
Tim Peters83c9edc2001-06-16 08:10:13 +0000247 return TESTNAME(raise_test_longlong_error);
Tim Peters91621db2001-06-12 20:10:01 +0000248}
249
Tim Peterse7c1f9b2001-06-14 00:55:41 +0000250#undef TESTNAME
251#undef TYPENAME
252#undef F_S_TO_PY
253#undef F_PY_TO_S
254#undef F_U_TO_PY
255#undef F_PY_TO_U
Tim Peterse7c1f9b2001-06-14 00:55:41 +0000256
257#endif /* ifdef HAVE_LONG_LONG */
258
Tim Peters91621db2001-06-12 20:10:01 +0000259
Tim Peters9ea17ac2001-02-02 05:57:15 +0000260static PyMethodDef TestMethods[] = {
Tim Peters91621db2001-06-12 20:10:01 +0000261 {"test_config", test_config, METH_VARARGS},
262 {"test_list_api", test_list_api, METH_VARARGS},
263 {"test_dict_iteration", test_dict_iteration, METH_VARARGS},
Tim Peterse7c1f9b2001-06-14 00:55:41 +0000264 {"test_long_api", test_long_api, METH_VARARGS},
Tim Peters91621db2001-06-12 20:10:01 +0000265#ifdef HAVE_LONG_LONG
266 {"test_longlong_api", test_longlong_api, METH_VARARGS},
267#endif
Tim Peters9ea17ac2001-02-02 05:57:15 +0000268 {NULL, NULL} /* sentinel */
269};
270
271DL_EXPORT(void)
Tim Petersd66595f2001-02-04 03:09:53 +0000272init_testcapi(void)
Tim Peters9ea17ac2001-02-02 05:57:15 +0000273{
274 PyObject *m, *d;
275
Tim Petersd66595f2001-02-04 03:09:53 +0000276 m = Py_InitModule("_testcapi", TestMethods);
Tim Peters9ea17ac2001-02-02 05:57:15 +0000277
Tim Petersd66595f2001-02-04 03:09:53 +0000278 TestError = PyErr_NewException("_testcapi.error", NULL, NULL);
Tim Peters9ea17ac2001-02-02 05:57:15 +0000279 d = PyModule_GetDict(m);
280 PyDict_SetItemString(d, "error", TestError);
281}