Skip to content

Commit 78c97c1

Browse files
committed
Improve c implementation of immutabledict
Avoids using the call methods and instead uses the dict c interface. Fixes: sqlalchemy#5871 Change-Id: I7a1211104da319b0793a149f1a24f9f95c9f6630
1 parent 57db20a commit 78c97c1

File tree

1 file changed

+24
-7
lines changed

1 file changed

+24
-7
lines changed

lib/sqlalchemy/cextension/immutabledict.c

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,13 @@ ImmutableDict_subscript(ImmutableDict *self, PyObject *key)
8080
PyObject *err_bytes;
8181
#endif
8282

83-
value = PyDict_GetItem((PyObject *)self->dict, key);
83+
value = PyDict_GetItemWithError(self->dict, key);
8484

8585
if (value == NULL) {
86+
if (PyErr_Occurred() != NULL) {
87+
// there was an error while hashing the key
88+
return NULL;
89+
}
8690
#if PY_MAJOR_VERSION >= 3
8791
err_bytes = PyUnicode_AsUTF8String(key);
8892
if (err_bytes == NULL)
@@ -280,20 +284,34 @@ static PyObject *
280284
ImmutableDict_get(ImmutableDict *self, PyObject *args)
281285
{
282286
PyObject *key;
287+
PyObject *value;
283288
PyObject *default_value = Py_None;
284289

285290
if (!PyArg_UnpackTuple(args, "key", 1, 2, &key, &default_value)) {
286291
return NULL;
287292
}
288293

294+
value = PyDict_GetItemWithError(self->dict, key);
289295

290-
return PyObject_CallMethod(self->dict, "get", "OO", key, default_value);
296+
if (value == NULL) {
297+
if (PyErr_Occurred() != NULL) {
298+
// there was an error while hashing the key
299+
return NULL;
300+
} else {
301+
// return default
302+
Py_INCREF(default_value);
303+
return default_value;
304+
}
305+
} else {
306+
Py_INCREF(value);
307+
return value;
308+
}
291309
}
292310

293311
static PyObject *
294312
ImmutableDict_keys(ImmutableDict *self)
295313
{
296-
return PyObject_CallMethod(self->dict, "keys", "");
314+
return PyDict_Keys(self->dict);
297315
}
298316

299317
static int
@@ -312,20 +330,19 @@ ImmutableDict_richcompare(ImmutableDict *self, PyObject *other, int op)
312330
static PyObject *
313331
ImmutableDict_iter(ImmutableDict *self)
314332
{
315-
return PyObject_CallMethod(self->dict, "__iter__", "");
333+
return PyObject_GetIter(self->dict);
316334
}
317335

318336
static PyObject *
319337
ImmutableDict_items(ImmutableDict *self)
320338
{
321-
return PyObject_CallMethod(self->dict, "items", "");
339+
return PyDict_Items(self->dict);
322340
}
323341

324342
static PyObject *
325343
ImmutableDict_values(ImmutableDict *self)
326344
{
327-
return PyObject_CallMethod(self->dict, "values", "");
328-
345+
return PyDict_Values(self->dict);
329346
}
330347

331348
static PyObject *

0 commit comments

Comments
 (0)