Skip to content

Commit c98600b

Browse files
gh-111789: Use PyDict_GetItemRef() in _ctypes (GH-111828)
1 parent 18203a6 commit c98600b

File tree

2 files changed

+61
-78
lines changed

2 files changed

+61
-78
lines changed

Modules/_ctypes/_ctypes.c

+46-58
Original file line numberDiff line numberDiff line change
@@ -243,26 +243,13 @@ PyDict_SetItemProxy(PyObject *dict, PyObject *key, PyObject *item)
243243
static int
244244
_PyDict_GetItemProxy(PyObject *dict, PyObject *key, PyObject **presult)
245245
{
246-
PyObject *item = PyDict_GetItemWithError(dict, key);
247-
if (item == NULL) {
248-
if (PyErr_Occurred()) {
249-
return -1;
250-
}
251-
*presult = NULL;
252-
return 0;
246+
int rc = PyDict_GetItemRef(dict, key, presult);
247+
PyObject *item = *presult;
248+
if (item && PyWeakref_CheckProxy(item)) {
249+
rc = PyWeakref_GetRef(item, presult);
250+
Py_DECREF(item);
253251
}
254-
255-
if (!PyWeakref_CheckProxy(item)) {
256-
*presult = Py_NewRef(item);
257-
return 0;
258-
}
259-
PyObject *ref;
260-
if (PyWeakref_GetRef(item, &ref) < 0) {
261-
return -1;
262-
}
263-
// ref is NULL if the referenced object was destroyed
264-
*presult = ref;
265-
return 0;
252+
return rc;
266253
}
267254

268255
/******************************************************************/
@@ -565,18 +552,19 @@ StructUnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds, int isSt
565552

566553
dict->paramfunc = StructUnionType_paramfunc;
567554

568-
fields = PyDict_GetItemWithError((PyObject *)dict, &_Py_ID(_fields_));
555+
if (PyDict_GetItemRef((PyObject *)dict, &_Py_ID(_fields_), &fields) < 0) {
556+
Py_DECREF(result);
557+
return NULL;
558+
}
569559
if (fields) {
570560
if (PyObject_SetAttr((PyObject *)result, &_Py_ID(_fields_), fields) < 0) {
571561
Py_DECREF(result);
562+
Py_DECREF(fields);
572563
return NULL;
573564
}
565+
Py_DECREF(fields);
574566
return (PyObject *)result;
575567
}
576-
else if (PyErr_Occurred()) {
577-
Py_DECREF(result);
578-
return NULL;
579-
}
580568
else {
581569
StgDictObject *basedict = PyType_stgdict((PyObject *)result->tp_base);
582570

@@ -1110,11 +1098,15 @@ PyCPointerType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
11101098
stgdict->paramfunc = PyCPointerType_paramfunc;
11111099
stgdict->flags |= TYPEFLAG_ISPOINTER;
11121100

1113-
proto = PyDict_GetItemWithError(typedict, &_Py_ID(_type_)); /* Borrowed ref */
1101+
if (PyDict_GetItemRef(typedict, &_Py_ID(_type_), &proto) < 0) {
1102+
Py_DECREF((PyObject *)stgdict);
1103+
return NULL;
1104+
}
11141105
if (proto) {
11151106
StgDictObject *itemdict;
11161107
const char *current_format;
11171108
if (-1 == PyCPointerType_SetProto(stgdict, proto)) {
1109+
Py_DECREF(proto);
11181110
Py_DECREF((PyObject *)stgdict);
11191111
return NULL;
11201112
}
@@ -1134,15 +1126,12 @@ PyCPointerType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
11341126
} else {
11351127
stgdict->format = _ctypes_alloc_format_string("&", current_format);
11361128
}
1129+
Py_DECREF(proto);
11371130
if (stgdict->format == NULL) {
11381131
Py_DECREF((PyObject *)stgdict);
11391132
return NULL;
11401133
}
11411134
}
1142-
else if (PyErr_Occurred()) {
1143-
Py_DECREF((PyObject *)stgdict);
1144-
return NULL;
1145-
}
11461135

11471136
/* create the new instance (which is a class,
11481137
since we are a metatype!) */
@@ -2461,58 +2450,61 @@ make_funcptrtype_dict(StgDictObject *stgdict)
24612450
stgdict->getfunc = NULL;
24622451
stgdict->ffi_type_pointer = ffi_type_pointer;
24632452

2464-
ob = PyDict_GetItemWithError((PyObject *)stgdict, &_Py_ID(_flags_));
2453+
if (PyDict_GetItemRef((PyObject *)stgdict, &_Py_ID(_flags_), &ob) < 0) {
2454+
return -1;
2455+
}
24652456
if (!ob || !PyLong_Check(ob)) {
2466-
if (!PyErr_Occurred()) {
2467-
PyErr_SetString(PyExc_TypeError,
2457+
PyErr_SetString(PyExc_TypeError,
24682458
"class must define _flags_ which must be an integer");
2469-
}
2459+
Py_XDECREF(ob);
24702460
return -1;
24712461
}
24722462
stgdict->flags = PyLong_AsUnsignedLongMask(ob) | TYPEFLAG_ISPOINTER;
2463+
Py_DECREF(ob);
24732464

24742465
/* _argtypes_ is optional... */
2475-
ob = PyDict_GetItemWithError((PyObject *)stgdict, &_Py_ID(_argtypes_));
2466+
if (PyDict_GetItemRef((PyObject *)stgdict, &_Py_ID(_argtypes_), &ob) < 0) {
2467+
return -1;
2468+
}
24762469
if (ob) {
24772470
converters = converters_from_argtypes(ob);
2478-
if (!converters)
2471+
if (!converters) {
2472+
Py_DECREF(ob);
24792473
return -1;
2480-
stgdict->argtypes = Py_NewRef(ob);
2474+
}
2475+
stgdict->argtypes = ob;
24812476
stgdict->converters = converters;
24822477
}
2483-
else if (PyErr_Occurred()) {
2478+
2479+
if (PyDict_GetItemRef((PyObject *)stgdict, &_Py_ID(_restype_), &ob) < 0) {
24842480
return -1;
24852481
}
2486-
2487-
ob = PyDict_GetItemWithError((PyObject *)stgdict, &_Py_ID(_restype_));
24882482
if (ob) {
24892483
if (ob != Py_None && !PyType_stgdict(ob) && !PyCallable_Check(ob)) {
24902484
PyErr_SetString(PyExc_TypeError,
24912485
"_restype_ must be a type, a callable, or None");
2486+
Py_DECREF(ob);
24922487
return -1;
24932488
}
2494-
stgdict->restype = Py_NewRef(ob);
2489+
stgdict->restype = ob;
24952490
if (PyObject_GetOptionalAttr(ob, &_Py_ID(_check_retval_),
24962491
&stgdict->checker) < 0)
24972492
{
24982493
return -1;
24992494
}
25002495
}
2501-
else if (PyErr_Occurred()) {
2496+
/* XXX later, maybe.
2497+
if (PyDict_GetItemRef((PyObject *)stgdict, &_Py _ID(_errcheck_), &ob) < 0) {
25022498
return -1;
25032499
}
2504-
/* XXX later, maybe.
2505-
ob = _PyDict_GetItemIdWithError((PyObject *)stgdict, &PyId__errcheck_);
25062500
if (ob) {
25072501
if (!PyCallable_Check(ob)) {
25082502
PyErr_SetString(PyExc_TypeError,
25092503
"_errcheck_ must be callable");
2504+
Py_DECREF(ob);
25102505
return -1;
25112506
}
2512-
stgdict->errcheck = Py_NewRef(ob);
2513-
}
2514-
else if (PyErr_Occurred()) {
2515-
return -1;
2507+
stgdict->errcheck = ob;
25162508
}
25172509
*/
25182510
return 0;
@@ -3812,13 +3804,12 @@ _get_arg(int *pindex, PyObject *name, PyObject *defval, PyObject *inargs, PyObje
38123804
return Py_NewRef(v);
38133805
}
38143806
if (kwds && name) {
3815-
v = PyDict_GetItemWithError(kwds, name);
3807+
if (PyDict_GetItemRef(kwds, name, &v) < 0) {
3808+
return NULL;
3809+
}
38163810
if (v) {
38173811
++*pindex;
3818-
return Py_NewRef(v);
3819-
}
3820-
else if (PyErr_Occurred()) {
3821-
return NULL;
3812+
return v;
38223813
}
38233814
}
38243815
if (defval) {
@@ -4870,15 +4861,12 @@ PyCArrayType_from_ctype(PyObject *itemtype, Py_ssize_t length)
48704861
return NULL;
48714862

48724863
PyObject *result;
4873-
if (_PyDict_GetItemProxy(cache, key, &result) < 0) {
4874-
Py_DECREF(key);
4875-
return NULL;
4876-
}
4877-
if (result) {
4864+
if (_PyDict_GetItemProxy(cache, key, &result) != 0) {
4865+
// found or error
48784866
Py_DECREF(key);
48794867
return result;
48804868
}
4881-
4869+
// not found
48824870
if (!PyType_Check(itemtype)) {
48834871
PyErr_SetString(PyExc_TypeError,
48844872
"Expected a type object");

Modules/_ctypes/callproc.c

+15-20
Original file line numberDiff line numberDiff line change
@@ -168,16 +168,18 @@ _ctypes_get_errobj(int **pspace)
168168
if (error_object_name == NULL)
169169
return NULL;
170170
}
171-
errobj = PyDict_GetItemWithError(dict, error_object_name);
171+
if (PyDict_GetItemRef(dict, error_object_name, &errobj) < 0) {
172+
return NULL;
173+
}
172174
if (errobj) {
173175
if (!PyCapsule_IsValid(errobj, CTYPES_CAPSULE_NAME_PYMEM)) {
174176
PyErr_SetString(PyExc_RuntimeError,
175177
"ctypes.error_object is an invalid capsule");
178+
Py_DECREF(errobj);
176179
return NULL;
177180
}
178-
Py_INCREF(errobj);
179181
}
180-
else if (!PyErr_Occurred()) {
182+
else {
181183
void *space = PyMem_Calloc(2, sizeof(int));
182184
if (space == NULL)
183185
return NULL;
@@ -192,9 +194,6 @@ _ctypes_get_errobj(int **pspace)
192194
return NULL;
193195
}
194196
}
195-
else {
196-
return NULL;
197-
}
198197
*pspace = (int *)PyCapsule_GetPointer(errobj, CTYPES_CAPSULE_NAME_PYMEM);
199198
return errobj;
200199
}
@@ -1922,13 +1921,11 @@ create_pointer_type(PyObject *module, PyObject *cls)
19221921
PyTypeObject *typ;
19231922
PyObject *key;
19241923

1925-
result = PyDict_GetItemWithError(_ctypes_ptrtype_cache, cls);
1926-
if (result) {
1927-
return Py_NewRef(result);
1928-
}
1929-
else if (PyErr_Occurred()) {
1930-
return NULL;
1924+
if (PyDict_GetItemRef(_ctypes_ptrtype_cache, cls, &result) != 0) {
1925+
// found or error
1926+
return result;
19311927
}
1928+
// not found
19321929
if (PyUnicode_CheckExact(cls)) {
19331930
PyObject *name = PyUnicode_FromFormat("LP_%U", cls);
19341931
result = PyObject_CallFunction((PyObject *)Py_TYPE(&PyCPointer_Type),
@@ -1986,16 +1983,14 @@ create_pointer_inst(PyObject *module, PyObject *arg)
19861983
PyObject *result;
19871984
PyObject *typ;
19881985

1989-
typ = PyDict_GetItemWithError(_ctypes_ptrtype_cache, (PyObject *)Py_TYPE(arg));
1990-
if (typ) {
1991-
return PyObject_CallOneArg(typ, arg);
1992-
}
1993-
else if (PyErr_Occurred()) {
1986+
if (PyDict_GetItemRef(_ctypes_ptrtype_cache, (PyObject *)Py_TYPE(arg), &typ) < 0) {
19941987
return NULL;
19951988
}
1996-
typ = create_pointer_type(NULL, (PyObject *)Py_TYPE(arg));
1997-
if (typ == NULL)
1998-
return NULL;
1989+
if (typ == NULL) {
1990+
typ = create_pointer_type(NULL, (PyObject *)Py_TYPE(arg));
1991+
if (typ == NULL)
1992+
return NULL;
1993+
}
19991994
result = PyObject_CallOneArg(typ, arg);
20001995
Py_DECREF(typ);
20011996
return result;

0 commit comments

Comments
 (0)