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