[issue42522] [C API] Add Py_Borrow() function: call Py_XDECREF() and return the object
STINNER Victor
report at bugs.python.org
Tue Dec 1 06:21:37 EST 2020
New submission from STINNER Victor <vstinner at python.org>:
I'm working on a script to migrate old C extension modules to the latest flavor of the Python C API:
https://github.com/pythoncapi/upgrade_pythoncapi
I would like to replace frame->f_code with PyFrame_GetCode(frame). The problem is that frame->f_code is a borrowed reference, whereas PyFrame_GetCode() returns a strong reference. Having a Py_Borrow() function would help to automate migration to PyFrame_GetCode():
static inline PyObject* Py_Borrow(PyObject *obj)
{
Py_XDECREF(obj);
return obj;
}
So frame->f_code can be replaced with Py_Borrow(PyFrame_GetCode(frame)).
Py_Borrow() is similar to Py_XDECREF() but can be used as an expression:
PyObject *code = Py_Borrow(PyFrame_GetCode(frame));
Py_Borrow() is the opposite of Py_XNewRef(). For example, Py_Borrow(Py_XNewRef(obj)) leaves the reference count unchanged (+1 and then -1).
My pratical problem is that it's not easy not add Py_XDECREF() call when converting C code to the new C API.
Example 1:
PyObject *code = frame->f_code;
This one is easy and can be written as:
PyObject *code = PyFrame_GetCode(frame); Py_XDECREF(code);
Example 2:
func(frame->f_code);
This one is more tricky. For example, the following code using a macro is wrong:
#define Py_BORROW(obj) (Py_XDECREF(obj), obj)
func(Py_BORROW(PyFrame_GetCode(frame->f_code)));
since it calls PyFrame_GetCode() twice when proceed by the C preprocessor and so leaks a reference:
func(Py_XDECREF(PyFrame_GetCode(frame->f_code)), PyFrame_GetCode(frame->f_code));
Attached PR implements Py_Borrow() function as a static inline function.
----------
components: C API
messages: 382237
nosy: vstinner
priority: normal
severity: normal
status: open
title: [C API] Add Py_Borrow() function: call Py_XDECREF() and return the object
versions: Python 3.10
_______________________________________
Python tracker <report at bugs.python.org>
<https://bugs.python.org/issue42522>
_______________________________________
More information about the Python-bugs-list
mailing list