1 // Header file providing new functions of the Python C API to old Python
2 // versions.
3 //
4 // File distributed under the MIT license.
5 //
6 // Homepage:
7 // https://github.com/pythoncapi/pythoncapi_compat
8 //
9 // Latest version:
10 // https://raw.githubusercontent.com/pythoncapi/pythoncapi_compat/master/pythoncapi_compat.h
11 //
12 // SPDX-License-Identifier: MIT
13 
14 #ifndef PYTHONCAPI_COMPAT
15 #define PYTHONCAPI_COMPAT
16 
17 #ifdef __cplusplus
18 extern "C" {
19 #endif
20 
21 #include <Python.h>
22 #include "frameobject.h"          // PyFrameObject, PyFrame_GetBack()
23 
24 
25 // Compatibility with Visual Studio 2013 and older which don't support
26 // the inline keyword in C (only in C++): use __inline instead.
27 #if (defined(_MSC_VER) && _MSC_VER < 1900 \
28      && !defined(__cplusplus) && !defined(inline))
29 #  define inline __inline
30 #  define PYTHONCAPI_COMPAT_MSC_INLINE
31    // These two macros are undefined at the end of this file
32 #endif
33 
34 
35 // Cast argument to PyObject* type.
36 #ifndef _PyObject_CAST
37 #  define _PyObject_CAST(op) ((PyObject*)(op))
38 #endif
39 #ifndef _PyObject_CAST_CONST
40 #  define _PyObject_CAST_CONST(op) ((const PyObject*)(op))
41 #endif
42 
43 
44 // bpo-42262 added Py_NewRef() to Python 3.10.0a3
45 #if PY_VERSION_HEX < 0x030A00A3 && !defined(Py_NewRef)
_Py_NewRef(PyObject * obj)46 static inline PyObject* _Py_NewRef(PyObject *obj)
47 {
48     Py_INCREF(obj);
49     return obj;
50 }
51 #define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
52 #endif
53 
54 
55 // bpo-42262 added Py_XNewRef() to Python 3.10.0a3
56 #if PY_VERSION_HEX < 0x030A00A3 && !defined(Py_XNewRef)
_Py_XNewRef(PyObject * obj)57 static inline PyObject* _Py_XNewRef(PyObject *obj)
58 {
59     Py_XINCREF(obj);
60     return obj;
61 }
62 #define Py_XNewRef(obj) _Py_XNewRef(_PyObject_CAST(obj))
63 #endif
64 
65 
66 // See https://bugs.python.org/issue42522
67 #if !defined(_Py_StealRef)
__Py_StealRef(PyObject * obj)68 static inline PyObject* __Py_StealRef(PyObject *obj)
69 {
70     Py_DECREF(obj);
71     return obj;
72 }
73 #define _Py_StealRef(obj) __Py_StealRef(_PyObject_CAST(obj))
74 #endif
75 
76 
77 // See https://bugs.python.org/issue42522
78 #if !defined(_Py_XStealRef)
__Py_XStealRef(PyObject * obj)79 static inline PyObject* __Py_XStealRef(PyObject *obj)
80 {
81     Py_XDECREF(obj);
82     return obj;
83 }
84 #define _Py_XStealRef(obj) __Py_XStealRef(_PyObject_CAST(obj))
85 #endif
86 
87 
88 // bpo-39573 added Py_SET_REFCNT() to Python 3.9.0a4
89 #if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_REFCNT)
_Py_SET_REFCNT(PyObject * ob,Py_ssize_t refcnt)90 static inline void _Py_SET_REFCNT(PyObject *ob, Py_ssize_t refcnt)
91 {
92     ob->ob_refcnt = refcnt;
93 }
94 #define Py_SET_REFCNT(ob, refcnt) _Py_SET_REFCNT(_PyObject_CAST(ob), refcnt)
95 #endif
96 
97 
98 // Py_SETREF() and Py_XSETREF() were added to Python 3.5.2.
99 // It is excluded from the limited C API.
100 #if (PY_VERSION_HEX < 0x03050200 && !defined(Py_SETREF)) && !defined(Py_LIMITED_API)
101 #define Py_SETREF(op, op2)                      \
102     do {                                        \
103         PyObject *_py_tmp = _PyObject_CAST(op); \
104         (op) = (op2);                           \
105         Py_DECREF(_py_tmp);                     \
106     } while (0)
107 
108 #define Py_XSETREF(op, op2)                     \
109     do {                                        \
110         PyObject *_py_tmp = _PyObject_CAST(op); \
111         (op) = (op2);                           \
112         Py_XDECREF(_py_tmp);                    \
113     } while (0)
114 #endif
115 
116 // bpo-39573 added Py_SET_TYPE() to Python 3.9.0a4
117 #if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_TYPE)
118 static inline void
_Py_SET_TYPE(PyObject * ob,PyTypeObject * type)119 _Py_SET_TYPE(PyObject *ob, PyTypeObject *type)
120 {
121     ob->ob_type = type;
122 }
123 #define Py_SET_TYPE(ob, type) _Py_SET_TYPE(_PyObject_CAST(ob), type)
124 #endif
125 
126 
127 // bpo-39573 added Py_SET_SIZE() to Python 3.9.0a4
128 #if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_SIZE)
129 static inline void
_Py_SET_SIZE(PyVarObject * ob,Py_ssize_t size)130 _Py_SET_SIZE(PyVarObject *ob, Py_ssize_t size)
131 {
132     ob->ob_size = size;
133 }
134 #define Py_SET_SIZE(ob, size) _Py_SET_SIZE((PyVarObject*)(ob), size)
135 #endif
136 
137 
138 // bpo-40421 added PyFrame_GetCode() to Python 3.9.0b1
139 #if PY_VERSION_HEX < 0x030900B1
140 static inline PyCodeObject*
PyFrame_GetCode(PyFrameObject * frame)141 PyFrame_GetCode(PyFrameObject *frame)
142 {
143     assert(frame != NULL);
144     assert(frame->f_code != NULL);
145     return (PyCodeObject*)Py_NewRef(frame->f_code);
146 }
147 #endif
148 
149 static inline PyCodeObject*
_PyFrame_GetCodeBorrow(PyFrameObject * frame)150 _PyFrame_GetCodeBorrow(PyFrameObject *frame)
151 {
152     return (PyCodeObject *)_Py_StealRef(PyFrame_GetCode(frame));
153 }
154 
155 
156 // bpo-40421 added PyFrame_GetCode() to Python 3.9.0b1
157 #if PY_VERSION_HEX < 0x030900B1 && !defined(PYPY_VERSION)
158 static inline PyFrameObject*
PyFrame_GetBack(PyFrameObject * frame)159 PyFrame_GetBack(PyFrameObject *frame)
160 {
161     assert(frame != NULL);
162     return (PyFrameObject*)Py_XNewRef(frame->f_back);
163 }
164 #endif
165 
166 #if !defined(PYPY_VERSION)
167 static inline PyFrameObject*
_PyFrame_GetBackBorrow(PyFrameObject * frame)168 _PyFrame_GetBackBorrow(PyFrameObject *frame)
169 {
170     return (PyFrameObject *)_Py_XStealRef(PyFrame_GetBack(frame));
171 }
172 #endif
173 
174 
175 // bpo-39947 added PyThreadState_GetInterpreter() to Python 3.9.0a5
176 #if PY_VERSION_HEX < 0x030900A5
177 static inline PyInterpreterState *
PyThreadState_GetInterpreter(PyThreadState * tstate)178 PyThreadState_GetInterpreter(PyThreadState *tstate)
179 {
180     assert(tstate != NULL);
181     return tstate->interp;
182 }
183 #endif
184 
185 
186 // bpo-40429 added PyThreadState_GetFrame() to Python 3.9.0b1
187 #if PY_VERSION_HEX < 0x030900B1 && !defined(PYPY_VERSION)
188 static inline PyFrameObject*
PyThreadState_GetFrame(PyThreadState * tstate)189 PyThreadState_GetFrame(PyThreadState *tstate)
190 {
191     assert(tstate != NULL);
192     return (PyFrameObject *)Py_XNewRef(tstate->frame);
193 }
194 #endif
195 
196 #if !defined(PYPY_VERSION)
197 static inline PyFrameObject*
_PyThreadState_GetFrameBorrow(PyThreadState * tstate)198 _PyThreadState_GetFrameBorrow(PyThreadState *tstate)
199 {
200     return (PyFrameObject *)_Py_XStealRef(PyThreadState_GetFrame(tstate));
201 }
202 #endif
203 
204 
205 // bpo-39947 added PyInterpreterState_Get() to Python 3.9.0a5
206 #if PY_VERSION_HEX < 0x030900A5
207 static inline PyInterpreterState *
PyInterpreterState_Get(void)208 PyInterpreterState_Get(void)
209 {
210     PyThreadState *tstate;
211     PyInterpreterState *interp;
212 
213     tstate = PyThreadState_GET();
214     if (tstate == NULL) {
215         Py_FatalError("GIL released (tstate is NULL)");
216     }
217     interp = tstate->interp;
218     if (interp == NULL) {
219         Py_FatalError("no current interpreter");
220     }
221     return interp;
222 }
223 #endif
224 
225 
226 // bpo-39947 added PyInterpreterState_Get() to Python 3.9.0a6
227 #if 0x030700A1 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x030900A6 && !defined(PYPY_VERSION)
228 static inline uint64_t
229 PyThreadState_GetID(PyThreadState *tstate)
230 {
231     assert(tstate != NULL);
232     return tstate->id;
233 }
234 #endif
235 
236 
237 // bpo-37194 added PyObject_CallNoArgs() to Python 3.9.0a1
238 #if PY_VERSION_HEX < 0x030900A1
239 static inline PyObject*
PyObject_CallNoArgs(PyObject * func)240 PyObject_CallNoArgs(PyObject *func)
241 {
242     return PyObject_CallFunctionObjArgs(func, NULL);
243 }
244 #endif
245 
246 
247 // bpo-39245 made PyObject_CallOneArg() public (previously called
248 // _PyObject_CallOneArg) in Python 3.9.0a4
249 #if PY_VERSION_HEX < 0x030900A4
250 static inline PyObject*
PyObject_CallOneArg(PyObject * func,PyObject * arg)251 PyObject_CallOneArg(PyObject *func, PyObject *arg)
252 {
253     return PyObject_CallFunctionObjArgs(func, arg, NULL);
254 }
255 #endif
256 
257 
258 // bpo-1635741 added PyModule_AddObjectRef() to Python 3.10.0a3
259 #if PY_VERSION_HEX < 0x030A00A3
260 static inline int
PyModule_AddObjectRef(PyObject * module,const char * name,PyObject * value)261 PyModule_AddObjectRef(PyObject *module, const char *name, PyObject *value)
262 {
263     int res;
264     Py_XINCREF(value);
265     res = PyModule_AddObject(module, name, value);
266     if (res < 0) {
267         Py_XDECREF(value);
268     }
269     return res;
270 }
271 #endif
272 
273 
274 // bpo-40024 added PyModule_AddType() to Python 3.9.0a5
275 #if PY_VERSION_HEX < 0x030900A5
276 static inline int
PyModule_AddType(PyObject * module,PyTypeObject * type)277 PyModule_AddType(PyObject *module, PyTypeObject *type)
278 {
279     const char *name, *dot;
280 
281     if (PyType_Ready(type) < 0) {
282         return -1;
283     }
284 
285     // inline _PyType_Name()
286     name = type->tp_name;
287     assert(name != NULL);
288     dot = strrchr(name, '.');
289     if (dot != NULL) {
290         name = dot + 1;
291     }
292 
293     return PyModule_AddObjectRef(module, name, (PyObject *)type);
294 }
295 #endif
296 
297 
298 // bpo-40241 added PyObject_GC_IsTracked() to Python 3.9.0a6.
299 // bpo-4688 added _PyObject_GC_IS_TRACKED() to Python 2.7.0a2.
300 #if PY_VERSION_HEX < 0x030900A6 && !defined(PYPY_VERSION)
301 static inline int
PyObject_GC_IsTracked(PyObject * obj)302 PyObject_GC_IsTracked(PyObject* obj)
303 {
304     return (PyObject_IS_GC(obj) && _PyObject_GC_IS_TRACKED(obj));
305 }
306 #endif
307 
308 // bpo-40241 added PyObject_GC_IsFinalized() to Python 3.9.0a6.
309 // bpo-18112 added _PyGCHead_FINALIZED() to Python 3.4.0 final.
310 #if PY_VERSION_HEX < 0x030900A6 && PY_VERSION_HEX >= 0x030400F0 && !defined(PYPY_VERSION)
311 static inline int
PyObject_GC_IsFinalized(PyObject * obj)312 PyObject_GC_IsFinalized(PyObject *obj)
313 {
314     return (PyObject_IS_GC(obj) && _PyGCHead_FINALIZED((PyGC_Head *)(obj)-1));
315 }
316 #endif
317 
318 
319 // bpo-39573 added Py_IS_TYPE() to Python 3.9.0a4
320 #if PY_VERSION_HEX < 0x030900A4 && !defined(Py_IS_TYPE)
321 static inline int
_Py_IS_TYPE(const PyObject * ob,const PyTypeObject * type)322 _Py_IS_TYPE(const PyObject *ob, const PyTypeObject *type) {
323     return ob->ob_type == type;
324 }
325 #define Py_IS_TYPE(ob, type) _Py_IS_TYPE(_PyObject_CAST_CONST(ob), type)
326 #endif
327 
328 
329 // Py_UNUSED() was added to Python 3.4.0b2.
330 #if PY_VERSION_HEX < 0x030400B2 && !defined(Py_UNUSED)
331 #  if defined(__GNUC__) || defined(__clang__)
332 #    define Py_UNUSED(name) _unused_ ## name __attribute__((unused))
333 #  else
334 #    define Py_UNUSED(name) _unused_ ## name
335 #  endif
336 #endif
337 
338 
339 #ifdef PYTHONCAPI_COMPAT_MSC_INLINE
340 #  undef inline
341 #  undef PYTHONCAPI_COMPAT_MSC_INLINE
342 #endif
343 
344 #ifdef __cplusplus
345 }
346 #endif
347 #endif  // PYTHONCAPI_COMPAT
348