1 #include <stddef.h> // ptrdiff_t
2
3 #define PY_SSIZE_T_CLEAN
4 #include "parts.h"
5 #include "util.h"
6
7
8 static PyObject *
9 dict_check(PyObject *self, PyObject *obj)
10 {
11 NULLABLE(obj);
12 return PyLong_FromLong(PyDict_Check(obj));
13 }
14
15 static PyObject *
16 dict_checkexact(PyObject *self, PyObject *obj)
17 {
18 NULLABLE(obj);
19 return PyLong_FromLong(PyDict_CheckExact(obj));
20 }
21
22 static PyObject *
23 dict_new(PyObject *self, PyObject *Py_UNUSED(ignored))
24 {
25 return PyDict_New();
26 }
27
28 static PyObject *
29 dictproxy_new(PyObject *self, PyObject *obj)
30 {
31 NULLABLE(obj);
32 return PyDictProxy_New(obj);
33 }
34
35 static PyObject *
36 dict_clear(PyObject *self, PyObject *obj)
37 {
38 PyDict_Clear(obj);
39 Py_RETURN_NONE;
40 }
41
42 static PyObject *
43 dict_copy(PyObject *self, PyObject *obj)
44 {
45 NULLABLE(obj);
46 return PyDict_Copy(obj);
47 }
48
49 static PyObject *
50 dict_contains(PyObject *self, PyObject *args)
51 {
52 PyObject *obj, *key;
53 if (!PyArg_ParseTuple(args, "OO", &obj, &key)) {
54 return NULL;
55 }
56 NULLABLE(obj);
57 NULLABLE(key);
58 RETURN_INT(PyDict_Contains(obj, key));
59 }
60
61 static PyObject *
62 dict_size(PyObject *self, PyObject *obj)
63 {
64 NULLABLE(obj);
65 RETURN_SIZE(PyDict_Size(obj));
66 }
67
68 static PyObject *
69 dict_getitem(PyObject *self, PyObject *args)
70 {
71 PyObject *mapping, *key;
72 if (!PyArg_ParseTuple(args, "OO", &mapping, &key)) {
73 return NULL;
74 }
75 NULLABLE(mapping);
76 NULLABLE(key);
77 PyObject *value = PyDict_GetItem(mapping, key);
78 if (value == NULL) {
79 if (PyErr_Occurred()) {
80 return NULL;
81 }
82 return Py_NewRef(PyExc_KeyError);
83 }
84 return Py_NewRef(value);
85 }
86
87 static PyObject *
88 dict_getitemstring(PyObject *self, PyObject *args)
89 {
90 PyObject *mapping;
91 const char *key;
92 Py_ssize_t size;
93 if (!PyArg_ParseTuple(args, "Oz#", &mapping, &key, &size)) {
94 return NULL;
95 }
96 NULLABLE(mapping);
97 PyObject *value = PyDict_GetItemString(mapping, key);
98 if (value == NULL) {
99 if (PyErr_Occurred()) {
100 return NULL;
101 }
102 return Py_NewRef(PyExc_KeyError);
103 }
104 return Py_NewRef(value);
105 }
106
107 static PyObject *
108 dict_getitemwitherror(PyObject *self, PyObject *args)
109 {
110 PyObject *mapping, *key;
111 if (!PyArg_ParseTuple(args, "OO", &mapping, &key)) {
112 return NULL;
113 }
114 NULLABLE(mapping);
115 NULLABLE(key);
116 PyObject *value = PyDict_GetItemWithError(mapping, key);
117 if (value == NULL) {
118 if (PyErr_Occurred()) {
119 return NULL;
120 }
121 return Py_NewRef(PyExc_KeyError);
122 }
123 return Py_NewRef(value);
124 }
125
126 static PyObject *
127 dict_setitem(PyObject *self, PyObject *args)
128 {
129 PyObject *mapping, *key, *value;
130 if (!PyArg_ParseTuple(args, "OOO", &mapping, &key, &value)) {
131 return NULL;
132 }
133 NULLABLE(mapping);
134 NULLABLE(key);
135 NULLABLE(value);
136 RETURN_INT(PyDict_SetItem(mapping, key, value));
137 }
138
139 static PyObject *
140 dict_setitemstring(PyObject *self, PyObject *args)
141 {
142 PyObject *mapping, *value;
143 const char *key;
144 Py_ssize_t size;
145 if (!PyArg_ParseTuple(args, "Oz#O", &mapping, &key, &size, &value)) {
146 return NULL;
147 }
148 NULLABLE(mapping);
149 NULLABLE(value);
150 RETURN_INT(PyDict_SetItemString(mapping, key, value));
151 }
152
153 static PyObject *
154 dict_setdefault(PyObject *self, PyObject *args)
155 {
156 PyObject *mapping, *key, *defaultobj;
157 if (!PyArg_ParseTuple(args, "OOO", &mapping, &key, &defaultobj)) {
158 return NULL;
159 }
160 NULLABLE(mapping);
161 NULLABLE(key);
162 NULLABLE(defaultobj);
163 return PyDict_SetDefault(mapping, key, defaultobj);
164 }
165
166 static PyObject *
167 dict_delitem(PyObject *self, PyObject *args)
168 {
169 PyObject *mapping, *key;
170 if (!PyArg_ParseTuple(args, "OO", &mapping, &key)) {
171 return NULL;
172 }
173 NULLABLE(mapping);
174 NULLABLE(key);
175 RETURN_INT(PyDict_DelItem(mapping, key));
176 }
177
178 static PyObject *
179 dict_delitemstring(PyObject *self, PyObject *args)
180 {
181 PyObject *mapping;
182 const char *key;
183 Py_ssize_t size;
184 if (!PyArg_ParseTuple(args, "Oz#", &mapping, &key, &size)) {
185 return NULL;
186 }
187 NULLABLE(mapping);
188 RETURN_INT(PyDict_DelItemString(mapping, key));
189 }
190
191 static PyObject *
192 dict_keys(PyObject *self, PyObject *obj)
193 {
194 NULLABLE(obj);
195 return PyDict_Keys(obj);
196 }
197
198 static PyObject *
199 dict_values(PyObject *self, PyObject *obj)
200 {
201 NULLABLE(obj);
202 return PyDict_Values(obj);
203 }
204
205 static PyObject *
206 dict_items(PyObject *self, PyObject *obj)
207 {
208 NULLABLE(obj);
209 return PyDict_Items(obj);
210 }
211
212 static PyObject *
213 dict_next(PyObject *self, PyObject *args)
214 {
215 PyObject *mapping, *key = UNINITIALIZED_PTR, *value = UNINITIALIZED_PTR;
216 Py_ssize_t pos;
217 if (!PyArg_ParseTuple(args, "On", &mapping, &pos)) {
218 return NULL;
219 }
220 NULLABLE(mapping);
221 int rc = PyDict_Next(mapping, &pos, &key, &value);
222 if (rc != 0) {
223 return Py_BuildValue("inOO", rc, pos, key, value);
224 }
225 assert(key == UNINITIALIZED_PTR);
226 assert(value == UNINITIALIZED_PTR);
227 if (PyErr_Occurred()) {
228 return NULL;
229 }
230 Py_RETURN_NONE;
231 }
232
233 static PyObject *
234 dict_merge(PyObject *self, PyObject *args)
235 {
236 PyObject *mapping, *mapping2;
237 int override;
238 if (!PyArg_ParseTuple(args, "OOi", &mapping, &mapping2, &override)) {
239 return NULL;
240 }
241 NULLABLE(mapping);
242 NULLABLE(mapping2);
243 RETURN_INT(PyDict_Merge(mapping, mapping2, override));
244 }
245
246 static PyObject *
247 dict_update(PyObject *self, PyObject *args)
248 {
249 PyObject *mapping, *mapping2;
250 if (!PyArg_ParseTuple(args, "OO", &mapping, &mapping2)) {
251 return NULL;
252 }
253 NULLABLE(mapping);
254 NULLABLE(mapping2);
255 RETURN_INT(PyDict_Update(mapping, mapping2));
256 }
257
258 static PyObject *
259 dict_mergefromseq2(PyObject *self, PyObject *args)
260 {
261 PyObject *mapping, *seq;
262 int override;
263 if (!PyArg_ParseTuple(args, "OOi", &mapping, &seq, &override)) {
264 return NULL;
265 }
266 NULLABLE(mapping);
267 NULLABLE(seq);
268 RETURN_INT(PyDict_MergeFromSeq2(mapping, seq, override));
269 }
270
271
272 static PyMethodDef test_methods[] = {
273 {"dict_check", dict_check, METH_O},
274 {"dict_checkexact", dict_checkexact, METH_O},
275 {"dict_new", dict_new, METH_NOARGS},
276 {"dictproxy_new", dictproxy_new, METH_O},
277 {"dict_clear", dict_clear, METH_O},
278 {"dict_copy", dict_copy, METH_O},
279 {"dict_size", dict_size, METH_O},
280 {"dict_getitem", dict_getitem, METH_VARARGS},
281 {"dict_getitemwitherror", dict_getitemwitherror, METH_VARARGS},
282 {"dict_getitemstring", dict_getitemstring, METH_VARARGS},
283 {"dict_contains", dict_contains, METH_VARARGS},
284 {"dict_setitem", dict_setitem, METH_VARARGS},
285 {"dict_setitemstring", dict_setitemstring, METH_VARARGS},
286 {"dict_delitem", dict_delitem, METH_VARARGS},
287 {"dict_delitemstring", dict_delitemstring, METH_VARARGS},
288 {"dict_setdefault", dict_setdefault, METH_VARARGS},
289 {"dict_keys", dict_keys, METH_O},
290 {"dict_values", dict_values, METH_O},
291 {"dict_items", dict_items, METH_O},
292 {"dict_next", dict_next, METH_VARARGS},
293 {"dict_merge", dict_merge, METH_VARARGS},
294 {"dict_update", dict_update, METH_VARARGS},
295 {"dict_mergefromseq2", dict_mergefromseq2, METH_VARARGS},
296
297 {NULL},
298 };
299
300 int
301 _PyTestCapi_Init_Dict(PyObject *m)
302 {
303 if (PyModule_AddFunctions(m, test_methods) < 0) {
304 return -1;
305 }
306
307 return 0;
308 }