1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
|
++++++++++++++++++++++++++++
upgrade_pythoncapi.py script
++++++++++++++++++++++++++++
``upgrade_pythoncapi.py`` requires Python 3.6 or newer.
Usage
=====
Run the with no arguments to display command line options and list available
operations::
python3 upgrade_pythoncapi.py
Select files and directories
----------------------------
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.
Select operations
-----------------
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
Download pythoncapi_compat.h
----------------------------
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 Operations
==================
``upgrade_pythoncapi.py`` implements the following operations:
Py_TYPE
-------
* Replace ``op->ob_type`` with ``Py_TYPE(op)``.
Py_SIZE
-------
* Replace ``op->ob_size`` with ``Py_SIZE(op)``.
Py_REFCNT
---------
* Replace ``op->ob_refcnt`` with ``Py_REFCNT(op)``.
Py_SET_TYPE
-----------
* Replace ``obj->ob_type = type;`` with ``Py_SET_TYPE(obj, type);``.
* Replace ``Py_TYPE(obj) = type;`` with ``Py_SET_TYPE(obj, type);``.
Py_SET_SIZE
-----------
* Replace ``obj->ob_size = size;`` with ``Py_SET_SIZE(obj, size);``.
* Replace ``Py_SIZE(obj) = size;`` with ``Py_SET_SIZE(obj, size);``.
Py_SET_REFCNT
-------------
* Replace ``obj->ob_refcnt = refcnt;`` with ``Py_SET_REFCNT(obj, refcnt);``.
* Replace ``Py_REFCNT(obj) = refcnt;`` with ``Py_SET_REFCNT(obj, refcnt);``.
Py_Is
-----
* Replace ``x == Py_None`` with ``Py_IsNone(x)``.
* Replace ``x == Py_True`` with ``Py_IsTrue(x)``.
* Replace ``x == Py_False`` with ``Py_IsFalse(x)``.
* Replace ``x != Py_None`` with ``!Py_IsNone(x)``.
* Replace ``x != Py_True`` with ``!Py_IsTrue(x)``.
* Replace ``x != Py_False`` with ``!Py_IsFalse(x)``.
PyObject_NEW
------------
* Replace ``PyObject_NEW(...)`` with ``PyObject_New(...)``.
* Replace ``PyObject_NEW_VAR(...)`` with ``PyObject_NewVar(...)``.
PyMem_MALLOC
------------
* Replace ``PyMem_MALLOC(n)`` with ``PyMem_Malloc(n)``.
* Replace ``PyMem_REALLOC(ptr, n)`` with ``PyMem_Realloc(ptr, n)``.
* Replace ``PyMem_FREE(ptr)``, ``PyMem_DEL(ptr)`` and ``PyMem_Del(ptr)`` .
with ``PyMem_Free(n)``.
PyObject_MALLOC
---------------
* Replace ``PyObject_MALLOC(n)`` with ``PyObject_Malloc(n)``.
* Replace ``PyObject_REALLOC(ptr, n)`` with ``PyObject_Realloc(ptr, n)``.
* Replace ``PyObject_FREE(ptr)``, ``PyObject_DEL(ptr)``
and ``PyObject_Del(ptr)`` . with ``PyObject_Free(n)``.
PyFrame_GetBack
---------------
* Replace ``frame->f_back`` with ``_PyFrame_GetBackBorrow(frame)``.
PyFrame_GetCode
---------------
* Replace ``frame->f_code`` with ``_PyFrame_GetCodeBorrow(frame)``.
PyThreadState_GetInterpreter
----------------------------
* Replace ``tstate->interp`` with ``PyThreadState_GetInterpreter(tstate)``.
PyThreadState_GetFrame
----------------------
* Replace ``tstate->frame`` with ``_PyThreadState_GetFrameBorrow(tstate)``.
Experimental operations
-----------------------
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;`` with ``return Py_NewRef(res);``
* Replace ``x = y; Py_INCREF(x);`` with ``x = Py_NewRef(y);``
* Replace ``x = y; Py_INCREF(y);`` with ``x = Py_NewRef(y);``
* Replace ``Py_INCREF(y); x = y;`` with ``x = Py_NewRef(y);``
* ``Py_CLEAR``:
* Replace ``Py_XDECREF(var); var = NULL;`` with ``Py_CLEAR(var);``
* ``Py_SETREF``:
* Replace ``Py_DECREF(x); x = y;`` with ``Py_SETREF(x, y);``
* Replace ``Py_XDECREF(x); x = y;`` with ``Py_XSETREF(x, y);``
|