upgrade_pythoncapi.py requires Python 3.6 or newer.
Run the with no arguments to display command line options and list available operations:
python3 upgrade_pythoncapi.py
To upgrade module.c file, type:
python3 upgrade_pythoncapi.py module.c
To upgrade all C and C++ files (.c, .h, .cc, .cpp, .cxx and
.hpp files) in the directory/ directory, type:
python3 upgrade_pythoncapi.py directory/
Multiple filenames an directories can be specified on the command line.
Files are modified in-place! If a file is modified, a copy of the original file
is created with the .old suffix.
To only replace op->ob_type with Py_TYPE(op), select the Py_TYPE
operation with:
python3 upgrade_pythoncapi.py -o Py_TYPE module.c
Or the opposite, to apply all operations but leave op->ob_type unchanged,
deselect the Py_TYPE operation with:
python3 upgrade_pythoncapi.py -o all,-Py_TYPE module.c
Most upgrade_pythoncapi.py operations add #include
"pythoncapi_compat.h". You may have to download the pythoncapi_compat.h
header file to your project. It can be downloaded with:
python3 upgrade_pythoncapi.py --download PATH
upgrade_pythoncapi.py implements the following operations:
- Replace
op->ob_typewithPy_TYPE(op).
- Replace
op->ob_sizewithPy_SIZE(op).
- Replace
op->ob_refcntwithPy_REFCNT(op).
- Replace
obj->ob_type = type;withPy_SET_TYPE(obj, type);. - Replace
Py_TYPE(obj) = type;withPy_SET_TYPE(obj, type);.
- Replace
obj->ob_size = size;withPy_SET_SIZE(obj, size);. - Replace
Py_SIZE(obj) = size;withPy_SET_SIZE(obj, size);.
- Replace
obj->ob_refcnt = refcnt;withPy_SET_REFCNT(obj, refcnt);. - Replace
Py_REFCNT(obj) = refcnt;withPy_SET_REFCNT(obj, refcnt);.
- Replace
x == Py_NonewithPy_IsNone(x). - Replace
x == Py_TruewithPy_IsTrue(x). - Replace
x == Py_FalsewithPy_IsFalse(x). - Replace
x != Py_Nonewith!Py_IsNone(x). - Replace
x != Py_Truewith!Py_IsTrue(x). - Replace
x != Py_Falsewith!Py_IsFalse(x).
- Replace
PyObject_NEW(...)withPyObject_New(...). - Replace
PyObject_NEW_VAR(...)withPyObject_NewVar(...).
- Replace
PyMem_MALLOC(n)withPyMem_Malloc(n). - Replace
PyMem_REALLOC(ptr, n)withPyMem_Realloc(ptr, n). - Replace
PyMem_FREE(ptr),PyMem_DEL(ptr)andPyMem_Del(ptr). withPyMem_Free(n).
- Replace
PyObject_MALLOC(n)withPyObject_Malloc(n). - Replace
PyObject_REALLOC(ptr, n)withPyObject_Realloc(ptr, n). - Replace
PyObject_FREE(ptr),PyObject_DEL(ptr)andPyObject_Del(ptr). withPyObject_Free(n).
- Replace
frame->f_backwith_PyFrame_GetBackBorrow(frame).
- Replace
frame->f_codewith_PyFrame_GetCodeBorrow(frame).
- Replace
tstate->interpwithPyThreadState_GetInterpreter(tstate).
- Replace
tstate->framewith_PyThreadState_GetFrameBorrow(tstate).
The following operations are experimental (ex: can introduce compiler warnings)
and so not included in the all group, they have to be selected explicitly.
Example: -o all,Py_SETREF.
Experimental operations:
Py_NewRef:- Replace
Py_INCREF(res); return res;withreturn Py_NewRef(res); - Replace
x = y; Py_INCREF(x);withx = Py_NewRef(y); - Replace
x = y; Py_INCREF(y);withx = Py_NewRef(y); - Replace
Py_INCREF(y); x = y;withx = Py_NewRef(y);
- Replace
Py_CLEAR:- Replace
Py_XDECREF(var); var = NULL;withPy_CLEAR(var);
- Replace
Py_SETREF:- Replace
Py_DECREF(x); x = y;withPy_SETREF(x, y); - Replace
Py_XDECREF(x); x = y;withPy_XSETREF(x, y);
- Replace