Skip to content

Commit

Permalink
ctypes: Return existing pointer when possible
Browse files Browse the repository at this point in the history
Addresses pythongh-46376
  • Loading branch information
s1kpp committed Jul 23, 2023
1 parent 443d9b3 commit 0eeea13
Showing 1 changed file with 22 additions and 0 deletions.
22 changes: 22 additions & 0 deletions Modules/_ctypes/_ctypes.c
Original file line number Diff line number Diff line change
Expand Up @@ -5129,6 +5129,7 @@ static PyObject *
Pointer_get_contents(CDataObject *self, void *closure)
{
StgDictObject *stgdict;
PyObject *keep, *pointer_probe, *pointer_to_pointer;

if (*(void **)self->b_ptr == NULL) {
PyErr_SetString(PyExc_ValueError,
Expand All @@ -5138,6 +5139,27 @@ Pointer_get_contents(CDataObject *self, void *closure)

stgdict = PyObject_stgdict((PyObject *)self);
assert(stgdict); /* Cannot be NULL for pointer instances */

keep = GetKeepedObjects(self);
if (keep != NULL) {
// check if it's a pointer to a pointer:
// pointers will have '0' key in the _objects

pointer_probe = PyDict_GetItemString(keep, "0");

if (pointer_probe != NULL) {
pointer_to_pointer = PyDict_GetItemString(keep, "1");
if (pointer_to_pointer == NULL) {
PyErr_SetString(PyExc_ValueError,
"Unexpected NULL pointer in _objets");
}
// don't construct a new object,
// return existing one instead to preserve refcount
Py_INCREF(pointer_to_pointer);
return pointer_to_pointer;
}
}

return PyCData_FromBaseObj(stgdict->proto,
(PyObject *)self, 0,
*(void **)self->b_ptr);
Expand Down

0 comments on commit 0eeea13

Please sign in to comment.