New submission from STINNER Victor <vstin...@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 <rep...@bugs.python.org> <https://bugs.python.org/issue42522> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com