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 // Copyright Contributors to the pythoncapi_compat project.
7 //
8 // Permission is hereby granted, free of charge, to any person obtaining a copy
9 // of this software and associated documentation files (the "Software"), to deal
10 // in the Software without restriction, including without limitation the rights
11 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 // copies of the Software, and to permit persons to whom the Software is
13 // furnished to do so, subject to the following conditions:
14 //
15 // The above copyright notice and this permission notice shall be included in all
16 // copies or substantial portions of the Software.
17 //
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 // SOFTWARE.
25 //
26 // Homepage:
27 // https://github.com/pythoncapi/pythoncapi_compat
28 //
29 // Latest version:
30 // https://raw.githubusercontent.com/pythoncapi/pythoncapi_compat/master/pythoncapi_compat.h
31 //
32 // SPDX-License-Identifier: MIT
33 
34 #ifndef PYTHONCAPI_COMPAT
35 #define PYTHONCAPI_COMPAT
36 
37 #ifdef __cplusplus
38 extern "C" {
39 #endif
40 
41 #include <Python.h>
42 #include "frameobject.h"          // PyFrameObject, PyFrame_GetBack()
43 
44 
45 // Compatibility with Visual Studio 2013 and older which don't support
46 // the inline keyword in C (only in C++): use __inline instead.
47 #if (defined(_MSC_VER) && _MSC_VER < 1900 \
48      && !defined(__cplusplus) && !defined(inline))
49 #  define inline __inline
50 #  define PYTHONCAPI_COMPAT_MSC_INLINE
51    // These two macros are undefined at the end of this file
52 #endif
53 
54 
55 // Cast argument to PyObject* type.
56 #ifndef _PyObject_CAST
57 #  define _PyObject_CAST(op) ((PyObject*)(op))
58 #endif
59 #ifndef _PyObject_CAST_CONST
60 #  define _PyObject_CAST_CONST(op) ((const PyObject*)(op))
61 #endif
62 
63 
64 // bpo-42262 added Py_NewRef() to Python 3.10.0a3
65 #if PY_VERSION_HEX < 0x030A00A3 && !defined(Py_NewRef)
_Py_NewRef(PyObject * obj)66 static inline PyObject* _Py_NewRef(PyObject *obj)
67 {
68     Py_INCREF(obj);
69     return obj;
70 }
71 #define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
72 #endif
73 
74 
75 // bpo-42262 added Py_XNewRef() to Python 3.10.0a3
76 #if PY_VERSION_HEX < 0x030A00A3 && !defined(Py_XNewRef)
_Py_XNewRef(PyObject * obj)77 static inline PyObject* _Py_XNewRef(PyObject *obj)
78 {
79     Py_XINCREF(obj);
80     return obj;
81 }
82 #define Py_XNewRef(obj) _Py_XNewRef(_PyObject_CAST(obj))
83 #endif
84 
85 
86 // See https://bugs.python.org/issue42522
87 #if !defined(_Py_StealRef)
__Py_StealRef(PyObject * obj)88 static inline PyObject* __Py_StealRef(PyObject *obj)
89 {
90     Py_DECREF(obj);
91     return obj;
92 }
93 #define _Py_StealRef(obj) __Py_StealRef(_PyObject_CAST(obj))
94 #endif
95 
96 
97 // See https://bugs.python.org/issue42522
98 #if !defined(_Py_XStealRef)
__Py_XStealRef(PyObject * obj)99 static inline PyObject* __Py_XStealRef(PyObject *obj)
100 {
101     Py_XDECREF(obj);
102     return obj;
103 }
104 #define _Py_XStealRef(obj) __Py_XStealRef(_PyObject_CAST(obj))
105 #endif
106 
107 
108 // bpo-39573 added Py_SET_REFCNT() to Python 3.9.0a4
109 #if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_REFCNT)
_Py_SET_REFCNT(PyObject * ob,Py_ssize_t refcnt)110 static inline void _Py_SET_REFCNT(PyObject *ob, Py_ssize_t refcnt)
111 {
112     ob->ob_refcnt = refcnt;
113 }
114 #define Py_SET_REFCNT(ob, refcnt) _Py_SET_REFCNT(_PyObject_CAST(ob), refcnt)
115 #endif
116 
117 
118 // Py_SETREF() and Py_XSETREF() were added to Python 3.5.2.
119 // It is excluded from the limited C API.
120 #if (PY_VERSION_HEX < 0x03050200 && !defined(Py_SETREF)) && !defined(Py_LIMITED_API)
121 #define Py_SETREF(op, op2)                      \
122     do {                                        \
123         PyObject *_py_tmp = _PyObject_CAST(op); \
124         (op) = (op2);                           \
125         Py_DECREF(_py_tmp);                     \
126     } while (0)
127 
128 #define Py_XSETREF(op, op2)                     \
129     do {                                        \
130         PyObject *_py_tmp = _PyObject_CAST(op); \
131         (op) = (op2);                           \
132         Py_XDECREF(_py_tmp);                    \
133     } while (0)
134 #endif
135 
136 
137 // bpo-43753 added Py_Is(), Py_IsNone(), Py_IsTrue() and Py_IsFalse()
138 // to Python 3.10.0b1.
139 #if PY_VERSION_HEX < 0x030A00B1 && !defined(Py_Is)
140 #  define Py_Is(x, y) ((x) == (y))
141 #endif
142 #if PY_VERSION_HEX < 0x030A00B1 && !defined(Py_IsNone)
143 #  define Py_IsNone(x) Py_Is(x, Py_None)
144 #endif
145 #if PY_VERSION_HEX < 0x030A00B1 && !defined(Py_IsTrue)
146 #  define Py_IsTrue(x) Py_Is(x, Py_True)
147 #endif
148 #if PY_VERSION_HEX < 0x030A00B1 && !defined(Py_IsFalse)
149 #  define Py_IsFalse(x) Py_Is(x, Py_False)
150 #endif
151 
152 
153 // bpo-39573 added Py_SET_TYPE() to Python 3.9.0a4
154 #if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_TYPE)
155 static inline void
_Py_SET_TYPE(PyObject * ob,PyTypeObject * type)156 _Py_SET_TYPE(PyObject *ob, PyTypeObject *type)
157 {
158     ob->ob_type = type;
159 }
160 #define Py_SET_TYPE(ob, type) _Py_SET_TYPE(_PyObject_CAST(ob), type)
161 #endif
162 
163 
164 // bpo-39573 added Py_SET_SIZE() to Python 3.9.0a4
165 #if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_SIZE)
166 static inline void
_Py_SET_SIZE(PyVarObject * ob,Py_ssize_t size)167 _Py_SET_SIZE(PyVarObject *ob, Py_ssize_t size)
168 {
169     ob->ob_size = size;
170 }
171 #define Py_SET_SIZE(ob, size) _Py_SET_SIZE((PyVarObject*)(ob), size)
172 #endif
173 
174 
175 // bpo-40421 added PyFrame_GetCode() to Python 3.9.0b1
176 #if PY_VERSION_HEX < 0x030900B1
177 static inline PyCodeObject*
PyFrame_GetCode(PyFrameObject * frame)178 PyFrame_GetCode(PyFrameObject *frame)
179 {
180     assert(frame != NULL);
181     assert(frame->f_code != NULL);
182     return (PyCodeObject*)Py_NewRef(frame->f_code);
183 }
184 #endif
185 
186 static inline PyCodeObject*
_PyFrame_GetCodeBorrow(PyFrameObject * frame)187 _PyFrame_GetCodeBorrow(PyFrameObject *frame)
188 {
189     return (PyCodeObject *)_Py_StealRef(PyFrame_GetCode(frame));
190 }
191 
192 
193 // bpo-40421 added PyFrame_GetCode() to Python 3.9.0b1
194 #if PY_VERSION_HEX < 0x030900B1 && !defined(PYPY_VERSION)
195 static inline PyFrameObject*
PyFrame_GetBack(PyFrameObject * frame)196 PyFrame_GetBack(PyFrameObject *frame)
197 {
198     assert(frame != NULL);
199     return (PyFrameObject*)Py_XNewRef(frame->f_back);
200 }
201 #endif
202 
203 #if !defined(PYPY_VERSION)
204 static inline PyFrameObject*
_PyFrame_GetBackBorrow(PyFrameObject * frame)205 _PyFrame_GetBackBorrow(PyFrameObject *frame)
206 {
207     return (PyFrameObject *)_Py_XStealRef(PyFrame_GetBack(frame));
208 }
209 #endif
210 
211 
212 // bpo-39947 added PyThreadState_GetInterpreter() to Python 3.9.0a5
213 #if PY_VERSION_HEX < 0x030900A5
214 static inline PyInterpreterState *
PyThreadState_GetInterpreter(PyThreadState * tstate)215 PyThreadState_GetInterpreter(PyThreadState *tstate)
216 {
217     assert(tstate != NULL);
218     return tstate->interp;
219 }
220 #endif
221 
222 
223 // bpo-40429 added PyThreadState_GetFrame() to Python 3.9.0b1
224 #if PY_VERSION_HEX < 0x030900B1 && !defined(PYPY_VERSION)
225 static inline PyFrameObject*
PyThreadState_GetFrame(PyThreadState * tstate)226 PyThreadState_GetFrame(PyThreadState *tstate)
227 {
228     assert(tstate != NULL);
229     return (PyFrameObject *)Py_XNewRef(tstate->frame);
230 }
231 #endif
232 
233 #if !defined(PYPY_VERSION)
234 static inline PyFrameObject*
_PyThreadState_GetFrameBorrow(PyThreadState * tstate)235 _PyThreadState_GetFrameBorrow(PyThreadState *tstate)
236 {
237     return (PyFrameObject *)_Py_XStealRef(PyThreadState_GetFrame(tstate));
238 }
239 #endif
240 
241 
242 // bpo-39947 added PyInterpreterState_Get() to Python 3.9.0a5
243 #if PY_VERSION_HEX < 0x030900A5
244 static inline PyInterpreterState *
PyInterpreterState_Get(void)245 PyInterpreterState_Get(void)
246 {
247     PyThreadState *tstate;
248     PyInterpreterState *interp;
249 
250     tstate = PyThreadState_GET();
251     if (tstate == NULL) {
252         Py_FatalError("GIL released (tstate is NULL)");
253     }
254     interp = tstate->interp;
255     if (interp == NULL) {
256         Py_FatalError("no current interpreter");
257     }
258     return interp;
259 }
260 #endif
261 
262 
263 // bpo-39947 added PyInterpreterState_Get() to Python 3.9.0a6
264 #if 0x030700A1 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x030900A6 && !defined(PYPY_VERSION)
265 static inline uint64_t
266 PyThreadState_GetID(PyThreadState *tstate)
267 {
268     assert(tstate != NULL);
269     return tstate->id;
270 }
271 #endif
272 
273 
274 // bpo-37194 added PyObject_CallNoArgs() to Python 3.9.0a1
275 #if PY_VERSION_HEX < 0x030900A1
276 static inline PyObject*
PyObject_CallNoArgs(PyObject * func)277 PyObject_CallNoArgs(PyObject *func)
278 {
279     return PyObject_CallFunctionObjArgs(func, NULL);
280 }
281 #endif
282 
283 
284 // bpo-39245 made PyObject_CallOneArg() public (previously called
285 // _PyObject_CallOneArg) in Python 3.9.0a4
286 #if PY_VERSION_HEX < 0x030900A4
287 static inline PyObject*
PyObject_CallOneArg(PyObject * func,PyObject * arg)288 PyObject_CallOneArg(PyObject *func, PyObject *arg)
289 {
290     return PyObject_CallFunctionObjArgs(func, arg, NULL);
291 }
292 #endif
293 
294 
295 // bpo-1635741 added PyModule_AddObjectRef() to Python 3.10.0a3
296 #if PY_VERSION_HEX < 0x030A00A3
297 static inline int
PyModule_AddObjectRef(PyObject * module,const char * name,PyObject * value)298 PyModule_AddObjectRef(PyObject *module, const char *name, PyObject *value)
299 {
300     int res;
301     Py_XINCREF(value);
302     res = PyModule_AddObject(module, name, value);
303     if (res < 0) {
304         Py_XDECREF(value);
305     }
306     return res;
307 }
308 #endif
309 
310 
311 // bpo-40024 added PyModule_AddType() to Python 3.9.0a5
312 #if PY_VERSION_HEX < 0x030900A5
313 static inline int
PyModule_AddType(PyObject * module,PyTypeObject * type)314 PyModule_AddType(PyObject *module, PyTypeObject *type)
315 {
316     const char *name, *dot;
317 
318     if (PyType_Ready(type) < 0) {
319         return -1;
320     }
321 
322     // inline _PyType_Name()
323     name = type->tp_name;
324     assert(name != NULL);
325     dot = strrchr(name, '.');
326     if (dot != NULL) {
327         name = dot + 1;
328     }
329 
330     return PyModule_AddObjectRef(module, name, (PyObject *)type);
331 }
332 #endif
333 
334 
335 // bpo-40241 added PyObject_GC_IsTracked() to Python 3.9.0a6.
336 // bpo-4688 added _PyObject_GC_IS_TRACKED() to Python 2.7.0a2.
337 #if PY_VERSION_HEX < 0x030900A6 && !defined(PYPY_VERSION)
338 static inline int
PyObject_GC_IsTracked(PyObject * obj)339 PyObject_GC_IsTracked(PyObject* obj)
340 {
341     return (PyObject_IS_GC(obj) && _PyObject_GC_IS_TRACKED(obj));
342 }
343 #endif
344 
345 // bpo-40241 added PyObject_GC_IsFinalized() to Python 3.9.0a6.
346 // bpo-18112 added _PyGCHead_FINALIZED() to Python 3.4.0 final.
347 #if PY_VERSION_HEX < 0x030900A6 && PY_VERSION_HEX >= 0x030400F0 && !defined(PYPY_VERSION)
348 static inline int
PyObject_GC_IsFinalized(PyObject * obj)349 PyObject_GC_IsFinalized(PyObject *obj)
350 {
351     return (PyObject_IS_GC(obj) && _PyGCHead_FINALIZED((PyGC_Head *)(obj)-1));
352 }
353 #endif
354 
355 
356 // bpo-39573 added Py_IS_TYPE() to Python 3.9.0a4
357 #if PY_VERSION_HEX < 0x030900A4 && !defined(Py_IS_TYPE)
358 static inline int
_Py_IS_TYPE(const PyObject * ob,const PyTypeObject * type)359 _Py_IS_TYPE(const PyObject *ob, const PyTypeObject *type) {
360     return ob->ob_type == type;
361 }
362 #define Py_IS_TYPE(ob, type) _Py_IS_TYPE(_PyObject_CAST_CONST(ob), type)
363 #endif
364 
365 
366 // Py_UNUSED() was added to Python 3.4.0b2.
367 #if PY_VERSION_HEX < 0x030400B2 && !defined(Py_UNUSED)
368 #  if defined(__GNUC__) || defined(__clang__)
369 #    define Py_UNUSED(name) _unused_ ## name __attribute__((unused))
370 #  else
371 #    define Py_UNUSED(name) _unused_ ## name
372 #  endif
373 #endif
374 
375 
376 #ifdef PYTHONCAPI_COMPAT_MSC_INLINE
377 #  undef inline
378 #  undef PYTHONCAPI_COMPAT_MSC_INLINE
379 #endif
380 
381 #ifdef __cplusplus
382 }
383 #endif
384 #endif  // PYTHONCAPI_COMPAT
385