You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
C API: Remove PyObject_Init() return value #105944
PyObject_Init(), PyObject_INIT(), PyObject_InitVar() and PyObject_INIT_VAR() return their argument which is technically a borrowed reference. For me, this API is really surprising. Why would someone like to rely on the return value, since the result is already known: it's the input argument?
I propose to remove the return value of these 4 PyObject "INIT" functions.
On PyPI top 5,000 projects (2023-04-13), I found 3 projects using these functions, but none are affected by proposed change:
Cython (0.29.34)
pyjson5 (1.6.2)
boost-python copy by scipy 1.10.1
I searched for PyObject_INIT regex.
Cython is not affected, since it already ignores the result explicitly:
code.putln("(void) PyObject_INIT(o, t);")
There is also boost-python (used by scipy 1.10.1) which defines PyObject_INIT() if it's not defined... for Python 1.x :-) Python 3 is not affected.
Another option is to deprecate this function, but Cython currently uses it to implement a freelist optimization in ModuleNode.generate_new_function() of Cython/Compiler/ModuleNode.py.
It seems quite difficult to change, deprecate, and/or remove this function. I don't think that it's worth it to change its return value, so I just close the issue. I missed the fact that it's part of the stable ABI.
Activity
vstinner commentedon Jun 20, 2023
Hum, wait. It's part of the stable ABI, so we cannot just remove the return value without breaking the stable ABI :-(
vstinner commentedon Jun 20, 2023
Another option is to deprecate this function, but Cython currently uses it to implement a freelist optimization in
ModuleNode.generate_new_function()ofCython/Compiler/ModuleNode.py.vstinner commentedon Jun 20, 2023
Existing replacement APIs:
PyObject_New()(and_PyObject_New()) callsPyObject_Malloc()andPyObject_Init().PyType_GenericAlloc()(and_PyType_AllocNoTrack()) callsPyObject_Malloc(),_PyObject_Init()or_PyObject_InitVar(), and_PyObject_GC_TRACK().ronaldoussoren commentedon Jun 20, 2023
Isn't the borrowed reference harmless here because, as you write, the return value always is the first argument?
The return value allows you to write
return PyObject_Init(someValue, someType);which can lead to slightly more compact code.erlend-aasland commentedon Jun 20, 2023
As a data point,
memset,strcpy,strcatand company all return their first argument so you can use them for call chaining.vstinner commentedon Jun 23, 2023
It seems quite difficult to change, deprecate, and/or remove this function. I don't think that it's worth it to change its return value, so I just close the issue. I missed the fact that it's part of the stable ABI.