1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
|
/*
* C Extension module to test Python interpreter C APIs.
*
* The 'test_*' functions exported by this module are run as part of the
* standard Python regression test, via Lib/test/test_capi.py.
*/
#include "Python.h"
static PyObject *TestError; /* set to exception object in init */
/* Test #defines from config.h (particularly the SIZEOF_* defines).
The ones derived from autoconf on the UNIX-like OSes can be relied
upon (in the absence of sloppy cross-compiling), but the Windows
platforms have these hardcoded. Better safe than sorry.
*/
static PyObject*
sizeof_error(const char* fatname, const char* typename,
int expected, int got)
{
char buf[1024];
sprintf(buf, "%s #define == %d but sizeof(%s) == %d",
fatname, expected, typename, got);
PyErr_SetString(TestError, buf);
return (PyObject*)NULL;
}
static PyObject*
test_config(PyObject *self, PyObject *args)
{
if (!PyArg_ParseTuple(args, ":test_config"))
return NULL;
#define CHECK_SIZEOF(FATNAME, TYPE) \
if (FATNAME != sizeof(TYPE)) \
return sizeof_error(#FATNAME, #TYPE, FATNAME, sizeof(TYPE))
CHECK_SIZEOF(SIZEOF_INT, int);
CHECK_SIZEOF(SIZEOF_LONG, long);
CHECK_SIZEOF(SIZEOF_VOID_P, void*);
CHECK_SIZEOF(SIZEOF_TIME_T, time_t);
#ifdef HAVE_LONG_LONG
CHECK_SIZEOF(SIZEOF_LONG_LONG, LONG_LONG);
#endif
#undef CHECK_SIZEOF
Py_INCREF(Py_None);
return Py_None;
}
static PyObject*
test_list_api(PyObject *self, PyObject *args)
{
PyObject* list;
int i;
if (!PyArg_ParseTuple(args, ":test_list_api"))
return NULL;
/* SF bug 132008: PyList_Reverse segfaults */
#define NLIST 30
list = PyList_New(NLIST);
if (list == (PyObject*)NULL)
return (PyObject*)NULL;
/* list = range(NLIST) */
for (i = 0; i < NLIST; ++i) {
PyObject* anint = PyInt_FromLong(i);
if (anint == (PyObject*)NULL) {
Py_DECREF(list);
return (PyObject*)NULL;
}
PyList_SET_ITEM(list, i, anint);
}
/* list.reverse(), via PyList_Reverse() */
i = PyList_Reverse(list); /* should not blow up! */
if (i != 0) {
Py_DECREF(list);
return (PyObject*)NULL;
}
/* Check that list == range(29, -1, -1) now */
for (i = 0; i < NLIST; ++i) {
PyObject* anint = PyList_GET_ITEM(list, i);
if (PyInt_AS_LONG(anint) != NLIST-1-i) {
PyErr_SetString(TestError,
"test_list_api: reverse screwed up");
Py_DECREF(list);
return (PyObject*)NULL;
}
}
Py_DECREF(list);
#undef NLIST
Py_INCREF(Py_None);
return Py_None;
}
static int
test_dict_inner(int count)
{
int pos = 0, iterations = 0, i;
PyObject *dict = PyDict_New();
PyObject *v, *k;
if (dict == NULL)
return -1;
for (i = 0; i < count; i++) {
v = PyInt_FromLong(i);
PyDict_SetItem(dict, v, v);
Py_DECREF(v);
}
while (PyDict_Next(dict, &pos, &k, &v)) {
PyObject *o;
iterations++;
i = PyInt_AS_LONG(v) + 1;
o = PyInt_FromLong(i);
if (o == NULL)
return -1;
if (PyDict_SetItem(dict, k, o) < 0) {
Py_DECREF(o);
return -1;
}
Py_DECREF(o);
}
Py_DECREF(dict);
if (iterations != count) {
PyErr_SetString(
TestError,
"test_dict_iteration: dict iteration went wrong ");
return -1;
} else {
return 0;
}
}
static PyObject*
test_dict_iteration(PyObject* self, PyObject* args)
{
int i;
if (!PyArg_ParseTuple(args, ":test_dict_iteration"))
return NULL;
for (i = 0; i < 200; i++) {
if (test_dict_inner(i) < 0) {
return NULL;
}
}
Py_INCREF(Py_None);
return Py_None;
}
static PyMethodDef TestMethods[] = {
{"test_config", test_config, METH_VARARGS},
{"test_list_api", test_list_api, METH_VARARGS},
{"test_dict_iteration", test_dict_iteration, METH_VARARGS},
{NULL, NULL} /* sentinel */
};
DL_EXPORT(void)
init_testcapi(void)
{
PyObject *m, *d;
m = Py_InitModule("_testcapi", TestMethods);
TestError = PyErr_NewException("_testcapi.error", NULL, NULL);
d = PyModule_GetDict(m);
PyDict_SetItemString(d, "error", TestError);
}
|