Skip to content

Commit f80dea2

Browse files
author
Dino Viehland
committed
Add PyDict_GetItemRef
1 parent 05f670c commit f80dea2

22 files changed

Lines changed: 138 additions & 84 deletions

Include/dictobject.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,12 @@ PyAPI_DATA(PyTypeObject) PyDictValues_Type;
6767

6868

6969
PyAPI_FUNC(PyObject *) PyDict_New(void);
70+
#ifndef Py_NEWCAPI
7071
PyAPI_FUNC(PyObject *) PyDict_GetItem(PyObject *mp, PyObject *key);
72+
PyAPI_FUNC(PyObject *) PyDict_GetItemString(PyObject *dp, const char *key);
73+
#endif
74+
PyAPI_FUNC(PyObject *) PyDict_GetItemRef(PyObject *mp, PyObject *key);
75+
PyAPI_FUNC(PyObject *) PyDict_GetItemRefString(PyObject *dp, const char *key);
7176
#ifndef Py_LIMITED_API
7277
PyAPI_FUNC(PyObject *) _PyDict_GetItem_KnownHash(PyObject *mp, PyObject *key,
7378
Py_hash_t hash);
@@ -155,7 +160,6 @@ PyAPI_FUNC(int) PyDict_MergeFromSeq2(PyObject *d,
155160
PyObject *seq2,
156161
int override);
157162

158-
PyAPI_FUNC(PyObject *) PyDict_GetItemString(PyObject *dp, const char *key);
159163
#ifndef Py_LIMITED_API
160164
PyAPI_FUNC(PyObject *) _PyDict_GetItemId(PyObject *dp, struct _Py_Identifier *key);
161165
#endif /* !Py_LIMITED_API */

Modules/_csv.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -132,13 +132,11 @@ get_dialect_from_registry(PyObject * name_obj)
132132
{
133133
PyObject *dialect_obj;
134134

135-
dialect_obj = PyDict_GetItem(_csvstate_global->dialects, name_obj);
135+
dialect_obj = PyDict_GetItemRef(_csvstate_global->dialects, name_obj);
136136
if (dialect_obj == NULL) {
137137
if (!PyErr_Occurred())
138138
PyErr_Format(_csvstate_global->error_obj, "unknown dialect");
139139
}
140-
else
141-
Py_INCREF(dialect_obj);
142140
return dialect_obj;
143141
}
144142

Modules/_ctypes/_ctypes.c

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -238,15 +238,19 @@ PyObject *
238238
PyDict_GetItemProxy(PyObject *dict, PyObject *key)
239239
{
240240
PyObject *result;
241-
PyObject *item = PyDict_GetItem(dict, key);
241+
PyObject *item = PyDict_GetItemRef(dict, key);
242242

243243
if (item == NULL)
244244
return NULL;
245-
if (!PyWeakref_CheckProxy(item))
246-
return item;
247-
result = PyWeakref_GET_OBJECT(item);
248-
if (result == Py_None)
249-
return NULL;
245+
if (!PyWeakref_CheckProxy(item)) {
246+
result = item;
247+
} else {
248+
result = PyWeakref_GET_OBJECT(item);
249+
if (result == Py_None)
250+
result = NULL;
251+
}
252+
253+
Py_DECREF(item);
250254
return result;
251255
}
252256

@@ -3620,9 +3624,8 @@ _get_arg(int *pindex, PyObject *name, PyObject *defval, PyObject *inargs, PyObje
36203624
++*pindex;
36213625
return v;
36223626
}
3623-
if (kwds && name && (v = PyDict_GetItem(kwds, name))) {
3627+
if (kwds && name && (v = PyDict_GetItemRef(kwds, name))) {
36243628
++*pindex;
3625-
Py_INCREF(v);
36263629
return v;
36273630
}
36283631
if (defval) {
@@ -4197,13 +4200,17 @@ _init_pos_args(PyObject *self, PyTypeObject *type,
41974200
}
41984201
val = PyTuple_GetItemRef(args, i + index);
41994202
Py_DECREF(val);
4200-
if (kwds && PyDict_GetItem(kwds, name)) {
4201-
PyErr_Format(PyExc_TypeError,
4202-
"duplicate values for field %R",
4203-
name);
4204-
Py_DECREF(pair);
4205-
Py_DECREF(name);
4206-
return -1;
4203+
if (kwds) {
4204+
PyObject *existing = PyDict_GetItemRef(kwds, name);
4205+
if (existing) {
4206+
PyErr_Format(PyExc_TypeError,
4207+
"duplicate values for field %R",
4208+
name);
4209+
Py_DECREF(existing);
4210+
Py_DECREF(pair);
4211+
Py_DECREF(name);
4212+
return -1;
4213+
}
42074214
}
42084215

42094216
res = PyObject_SetAttr(self, name, val);

Modules/_ctypes/callproc.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -142,14 +142,14 @@ _ctypes_get_errobj(int **pspace)
142142
if (error_object_name == NULL)
143143
return NULL;
144144
}
145-
errobj = PyDict_GetItem(dict, error_object_name);
145+
errobj = PyDict_GetItemRef(dict, error_object_name);
146146
if (errobj) {
147147
if (!PyCapsule_IsValid(errobj, CTYPES_CAPSULE_NAME_PYMEM)) {
148+
Py_DECREF(errobj);
148149
PyErr_SetString(PyExc_RuntimeError,
149150
"ctypes.error_object is an invalid capsule");
150151
return NULL;
151152
}
152-
Py_INCREF(errobj);
153153
}
154154
else {
155155
void *space = PyMem_Malloc(sizeof(int) * 2);
@@ -1676,9 +1676,8 @@ POINTER(PyObject *self, PyObject *cls)
16761676
PyObject *key;
16771677
char *buf;
16781678

1679-
result = PyDict_GetItem(_ctypes_ptrtype_cache, cls);
1679+
result = PyDict_GetItemRef(_ctypes_ptrtype_cache, cls);
16801680
if (result) {
1681-
Py_INCREF(result);
16821681
return result;
16831682
}
16841683
if (PyUnicode_CheckExact(cls)) {
@@ -1741,10 +1740,12 @@ pointer(PyObject *self, PyObject *arg)
17411740
PyObject *typ;
17421741

17431742
PyTypeObject *arg_type = Py_GetType(arg);
1744-
typ = PyDict_GetItem(_ctypes_ptrtype_cache, (PyObject *)arg_type);
1743+
typ = PyDict_GetItemRef(_ctypes_ptrtype_cache, (PyObject *)arg_type);
17451744
if (typ) {
17461745
Py_DECREF(arg_type);
1747-
return PyObject_CallFunctionObjArgs(typ, arg, NULL);
1746+
result = PyObject_CallFunctionObjArgs(typ, arg, NULL);
1747+
Py_DECREF(typ);
1748+
return result;
17481749
}
17491750
typ = POINTER(NULL, (PyObject *)arg_type);
17501751
Py_DECREF(arg_type);

Modules/_elementtree.c

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -324,19 +324,22 @@ static PyObject*
324324
get_attrib_from_keywords(PyObject *kwds)
325325
{
326326
PyObject *attrib_str = PyUnicode_FromString("attrib");
327-
PyObject *attrib = PyDict_GetItem(kwds, attrib_str);
327+
PyObject *attrib = PyDict_GetItemRef(kwds, attrib_str);
328328

329329
if (attrib) {
330330
/* If attrib was found in kwds, copy its value and remove it from
331331
* kwds
332332
*/
333333
if (!PyDict_Check(attrib)) {
334+
Py_DECREF(attrib);
334335
Py_DECREF(attrib_str);
335336
PyErr_Format(PyExc_TypeError, "attrib must be dict, not %T",
336337
attrib);
337338
return NULL;
338339
}
339-
attrib = PyDict_Copy(attrib);
340+
PyObject *copy = PyDict_Copy(attrib);
341+
Py_DECREF(attrib);
342+
attrib = copy;
340343
PyDict_DelItem(kwds, attrib_str);
341344
} else {
342345
attrib = PyDict_New();
@@ -1341,17 +1344,16 @@ _elementtree_Element_get_impl(ElementObject *self, PyObject *key,
13411344
PyObject *default_value)
13421345
/*[clinic end generated code: output=523c614142595d75 input=ee153bbf8cdb246e]*/
13431346
{
1344-
PyObject* value;
1347+
PyObject* value = NULL;
13451348

1346-
if (!self->extra || self->extra->attrib == Py_None)
1349+
if (self->extra && self->extra->attrib != Py_None)
1350+
value = PyDict_GetItemRef(self->extra->attrib, key);
1351+
1352+
if (!value) {
13471353
value = default_value;
1348-
else {
1349-
value = PyDict_GetItem(self->extra->attrib, key);
1350-
if (!value)
1351-
value = default_value;
1354+
Py_INCREF(value);
13521355
}
13531356

1354-
Py_INCREF(value);
13551357
return value;
13561358
}
13571359

@@ -2790,11 +2792,9 @@ makeuniversal(XMLParserObject* self, const char* string)
27902792
if (!key)
27912793
return NULL;
27922794

2793-
value = PyDict_GetItem(self->names, key);
2795+
value = PyDict_GetItemRef(self->names, key);
27942796

2795-
if (value) {
2796-
Py_INCREF(value);
2797-
} else {
2797+
if (!value) {
27982798
/* new name. convert to universal name, and decode as
27992799
necessary */
28002800

@@ -2916,7 +2916,7 @@ expat_default_handler(XMLParserObject* self, const XML_Char* data_in,
29162916
if (!key)
29172917
return;
29182918

2919-
value = PyDict_GetItem(self->entity, key);
2919+
value = PyDict_GetItemRef(self->entity, key);
29202920

29212921
if (value) {
29222922
if (TreeBuilder_CheckExact(self->target))
@@ -2927,6 +2927,7 @@ expat_default_handler(XMLParserObject* self, const XML_Char* data_in,
29272927
res = PyObject_CallFunctionObjArgs(self->handle_data, value, NULL);
29282928
else
29292929
res = NULL;
2930+
Py_DECREF(value);
29302931
Py_XDECREF(res);
29312932
} else if (!PyErr_Occurred()) {
29322933
/* Report the first error, not the last */

Modules/_json.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -750,9 +750,8 @@ _parse_object_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ss
750750
key = scanstring_unicode(pystr, idx + 1, s->strict, &next_idx);
751751
if (key == NULL)
752752
goto bail;
753-
memokey = PyDict_GetItem(s->memo, key);
753+
memokey = PyDict_GetItemRef(s->memo, key);
754754
if (memokey != NULL) {
755-
Py_INCREF(memokey);
756755
Py_DECREF(key);
757756
key = memokey;
758757
}

Modules/_sqlite/cache.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ PyObject* pysqlite_cache_get(pysqlite_Cache* self, PyObject* args)
123123
pysqlite_Node* ptr;
124124
PyObject* data;
125125

126-
node = (pysqlite_Node*)PyDict_GetItem(self->mapping, key);
126+
node = (pysqlite_Node*)PyDict_GetItemRef(self->mapping, key);
127127
if (node) {
128128
/* an entry for this key already exists in the cache */
129129

@@ -160,6 +160,8 @@ PyObject* pysqlite_cache_get(pysqlite_Cache* self, PyObject* args)
160160
self->first = node;
161161
}
162162
ptr->prev = node;
163+
164+
Py_DECREF(node); // linked list has a ref
163165
}
164166
} else {
165167
/* There is no entry for this key in the cache, yet. We'll insert a new

Modules/_sqlite/cursor.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ PyObject* _pysqlite_get_converter(PyObject* key)
107107
return NULL;
108108
}
109109

110-
retval = PyDict_GetItem(_pysqlite_converters, upcase_key);
110+
retval = PyDict_GetItemRef(_pysqlite_converters, upcase_key);
111111
Py_DECREF(upcase_key);
112112

113113
return retval;
@@ -181,16 +181,16 @@ int pysqlite_build_row_cast_map(pysqlite_Cursor* self)
181181

182182
if (!converter) {
183183
converter = Py_None;
184+
Py_INCREF(converter);
184185
}
185186

186187
if (PyList_Append(self->row_cast_map, converter) != 0) {
187-
if (converter != Py_None) {
188-
Py_DECREF(converter);
189-
}
188+
Py_DECREF(converter);
190189
Py_CLEAR(self->row_cast_map);
191190

192191
return -1;
193192
}
193+
Py_DECREF(converter);
194194
}
195195

196196
return 0;

Modules/_sqlite/microprotocols.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,11 @@ pysqlite_microprotocols_adapt(PyObject *obj, PyObject *proto, PyObject *alt)
8686
if (!key) {
8787
return NULL;
8888
}
89-
adapter = PyDict_GetItem(psyco_adapters, key);
89+
adapter = PyDict_GetItemRef(psyco_adapters, key);
9090
Py_DECREF(key);
9191
if (adapter) {
9292
PyObject *adapted = PyObject_CallFunctionObjArgs(adapter, obj, NULL);
93+
Py_DECREF(adapter);
9394
return adapted;
9495
}
9596

Modules/_sre.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1953,10 +1953,11 @@ match_getindex(MatchObject* self, PyObject* index)
19531953
i = -1;
19541954

19551955
if (self->pattern->groupindex) {
1956-
index = PyDict_GetItem(self->pattern->groupindex, index);
1956+
index = PyDict_GetItemRef(self->pattern->groupindex, index);
19571957
if (index && PyLong_Check(index)) {
19581958
i = PyLong_AsSsize_t(index);
19591959
}
1960+
Py_XDECREF(index);
19601961
}
19611962

19621963
return i;

0 commit comments

Comments
 (0)