Skip to content

Commit eb0d992

Browse files
committed
Slight adaptation of Michael Hudson's patch to test PyDict_Next()
(with modification of existing dict elements!). This is part of SF patch #409864: lazy fix for Pings bizarre scoping crash. The adaptation I made to Michael's patch was to change the error handling to avoid masking other errors (moving the specific error message to inside test_dict_inner()), and to insert a test for dict==NULL at the start.
1 parent 361c535 commit eb0d992

1 file changed

Lines changed: 62 additions & 0 deletions

File tree

Modules/_testcapimodule.c

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,71 @@ test_list_api(PyObject *self, PyObject *args)
9595
return Py_None;
9696
}
9797

98+
static int
99+
test_dict_inner(int count)
100+
{
101+
int pos = 0, iterations = 0, i;
102+
PyObject *dict = PyDict_New();
103+
PyObject *v, *k;
104+
105+
if (dict == NULL)
106+
return -1;
107+
108+
for (i = 0; i < count; i++) {
109+
v = PyInt_FromLong(i);
110+
PyDict_SetItem(dict, v, v);
111+
Py_DECREF(v);
112+
}
113+
114+
while (PyDict_Next(dict, &pos, &k, &v)) {
115+
PyObject *o;
116+
iterations++;
117+
118+
i = PyInt_AS_LONG(v) + 1;
119+
o = PyInt_FromLong(i);
120+
if (o == NULL)
121+
return -1;
122+
if (PyDict_SetItem(dict, k, o) < 0) {
123+
Py_DECREF(o);
124+
return -1;
125+
}
126+
Py_DECREF(o);
127+
}
128+
129+
Py_DECREF(dict);
130+
131+
if (iterations != count) {
132+
PyErr_SetString(
133+
TestError,
134+
"test_dict_iteration: dict iteration went wrong ");
135+
return -1;
136+
} else {
137+
return 0;
138+
}
139+
}
140+
141+
static PyObject*
142+
test_dict_iteration(PyObject* self, PyObject* args)
143+
{
144+
int i;
145+
146+
if (!PyArg_ParseTuple(args, ":test_dict_iteration"))
147+
return NULL;
148+
149+
for (i = 0; i < 200; i++) {
150+
if (test_dict_inner(i) < 0) {
151+
return NULL;
152+
}
153+
}
154+
155+
Py_INCREF(Py_None);
156+
return Py_None;
157+
}
158+
98159
static PyMethodDef TestMethods[] = {
99160
{"test_config", test_config, METH_VARARGS},
100161
{"test_list_api", test_list_api, METH_VARARGS},
162+
{"test_dict_iteration", test_dict_iteration, METH_VARARGS},
101163
{NULL, NULL} /* sentinel */
102164
};
103165

0 commit comments

Comments
 (0)