1
- // Header file providing new functions of the Python C API to old Python
2
- // versions.
1
+ // Header file providing new C API functions to old Python versions.
3
2
//
4
- // File distributed under the MIT license.
3
+ // File distributed under the Zero Clause BSD (0BSD) license.
5
4
// Copyright Contributors to the pythoncapi_compat project.
6
5
//
7
6
// Homepage:
10
9
// Latest version:
11
10
// https://github.com/raw/pythoncapi/pythoncapi_compat/master/pythoncapi_compat.h
12
11
//
13
- // SPDX-License-Identifier: MIT
12
+ // SPDX-License-Identifier: 0BSD
14
13
15
14
#ifndef PYTHONCAPI_COMPAT
16
15
#define PYTHONCAPI_COMPAT
@@ -27,24 +26,34 @@ extern "C" {
27
26
// the inline keyword in C (only in C++): use __inline instead.
28
27
#if (defined(_MSC_VER ) && _MSC_VER < 1900 \
29
28
&& !defined(__cplusplus ) && !defined(inline ))
30
- # define inline __inline
31
- # define PYTHONCAPI_COMPAT_MSC_INLINE
32
- // These two macros are undefined at the end of this file
29
+ # define PYCAPI_COMPAT_INLINE ( TYPE static __inline TYPE
30
+ #else
31
+ # define PYCAPI_COMPAT_STATIC_INLINE ( TYPE ) static inline TYPE
33
32
#endif
34
33
35
34
35
+ // C++ compatibility
36
+ #ifdef __cplusplus
37
+ # define PYCAPI_COMPAT_CAST (TYPE , EXPR ) reinterpret_cast<TYPE>(EXPR)
38
+ # define PYCAPI_COMPAT_NULL nullptr
39
+ #else
40
+ # define PYCAPI_COMPAT_CAST (TYPE , EXPR ) (TYPE)(EXPR)
41
+ # define PYCAPI_COMPAT_NULL NULL
42
+ #endif
43
+
36
44
// Cast argument to PyObject* type.
37
45
#ifndef _PyObject_CAST
38
- # define _PyObject_CAST (op ) (( PyObject*)(op) )
46
+ # define _PyObject_CAST (op ) PYCAPI_COMPAT_CAST( PyObject*, op )
39
47
#endif
40
48
#ifndef _PyObject_CAST_CONST
41
- # define _PyObject_CAST_CONST (op ) (( const PyObject*)(op) )
49
+ # define _PyObject_CAST_CONST (op ) PYCAPI_COMPAT_CAST( const PyObject*, op )
42
50
#endif
43
51
44
52
45
53
// bpo-42262 added Py_NewRef() to Python 3.10.0a3
46
54
#if PY_VERSION_HEX < 0x030A00A3 && !defined(Py_NewRef )
47
- static inline PyObject * _Py_NewRef (PyObject * obj )
55
+ PYCAPI_COMPAT_STATIC_INLINE (PyObject * )
56
+ _Py_NewRef (PyObject * obj )
48
57
{
49
58
Py_INCREF (obj );
50
59
return obj ;
@@ -55,7 +64,8 @@ static inline PyObject* _Py_NewRef(PyObject *obj)
55
64
56
65
// bpo-42262 added Py_XNewRef() to Python 3.10.0a3
57
66
#if PY_VERSION_HEX < 0x030A00A3 && !defined(Py_XNewRef )
58
- static inline PyObject * _Py_XNewRef (PyObject * obj )
67
+ PYCAPI_COMPAT_STATIC_INLINE (PyObject * )
68
+ _Py_XNewRef (PyObject * obj )
59
69
{
60
70
Py_XINCREF (obj );
61
71
return obj ;
@@ -66,7 +76,8 @@ static inline PyObject* _Py_XNewRef(PyObject *obj)
66
76
67
77
// See https://bugs.python.org/issue42522
68
78
#if !defined(_Py_StealRef )
69
- static inline PyObject * __Py_StealRef (PyObject * obj )
79
+ PYCAPI_COMPAT_STATIC_INLINE (PyObject * )
80
+ __Py_StealRef (PyObject * obj )
70
81
{
71
82
Py_DECREF (obj );
72
83
return obj ;
@@ -77,7 +88,8 @@ static inline PyObject* __Py_StealRef(PyObject *obj)
77
88
78
89
// See https://bugs.python.org/issue42522
79
90
#if !defined(_Py_XStealRef )
80
- static inline PyObject * __Py_XStealRef (PyObject * obj )
91
+ PYCAPI_COMPAT_STATIC_INLINE (PyObject * )
92
+ __Py_XStealRef (PyObject * obj )
81
93
{
82
94
Py_XDECREF (obj );
83
95
return obj ;
@@ -88,7 +100,8 @@ static inline PyObject* __Py_XStealRef(PyObject *obj)
88
100
89
101
// bpo-39573 added Py_SET_REFCNT() to Python 3.9.0a4
90
102
#if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_REFCNT )
91
- static inline void _Py_SET_REFCNT (PyObject * ob , Py_ssize_t refcnt )
103
+ PYCAPI_COMPAT_STATIC_INLINE (void )
104
+ _Py_SET_REFCNT (PyObject * ob , Py_ssize_t refcnt )
92
105
{
93
106
ob -> ob_refcnt = refcnt ;
94
107
}
@@ -133,7 +146,7 @@ static inline void _Py_SET_REFCNT(PyObject *ob, Py_ssize_t refcnt)
133
146
134
147
// bpo-39573 added Py_SET_TYPE() to Python 3.9.0a4
135
148
#if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_TYPE )
136
- static inline void
149
+ PYCAPI_COMPAT_STATIC_INLINE ( void )
137
150
_Py_SET_TYPE (PyObject * ob , PyTypeObject * type )
138
151
{
139
152
ob -> ob_type = type ;
@@ -144,7 +157,7 @@ _Py_SET_TYPE(PyObject *ob, PyTypeObject *type)
144
157
145
158
// bpo-39573 added Py_SET_SIZE() to Python 3.9.0a4
146
159
#if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_SIZE )
147
- static inline void
160
+ PYCAPI_COMPAT_STATIC_INLINE ( void )
148
161
_Py_SET_SIZE (PyVarObject * ob , Py_ssize_t size )
149
162
{
150
163
ob -> ob_size = size ;
@@ -155,85 +168,88 @@ _Py_SET_SIZE(PyVarObject *ob, Py_ssize_t size)
155
168
156
169
// bpo-40421 added PyFrame_GetCode() to Python 3.9.0b1
157
170
#if PY_VERSION_HEX < 0x030900B1
158
- static inline PyCodeObject *
171
+ PYCAPI_COMPAT_STATIC_INLINE ( PyCodeObject * )
159
172
PyFrame_GetCode (PyFrameObject * frame )
160
173
{
161
- assert (frame != NULL );
162
- assert (frame -> f_code != NULL );
163
- return (PyCodeObject * ) Py_NewRef (frame -> f_code );
174
+ assert (frame != PYCAPI_COMPAT_NULL );
175
+ assert (frame -> f_code != PYCAPI_COMPAT_NULL );
176
+ return PYCAPI_COMPAT_CAST (PyCodeObject * , Py_NewRef (frame -> f_code ) );
164
177
}
165
178
#endif
166
179
167
- static inline PyCodeObject *
180
+ PYCAPI_COMPAT_STATIC_INLINE ( PyCodeObject * )
168
181
_PyFrame_GetCodeBorrow (PyFrameObject * frame )
169
182
{
170
- return (PyCodeObject * )_Py_StealRef (PyFrame_GetCode (frame ));
183
+ return PYCAPI_COMPAT_CAST (PyCodeObject * ,
184
+ _Py_StealRef (PyFrame_GetCode (frame )));
171
185
}
172
186
173
187
174
188
// bpo-40421 added PyFrame_GetCode() to Python 3.9.0b1
175
189
#if PY_VERSION_HEX < 0x030900B1 && !defined(PYPY_VERSION )
176
- static inline PyFrameObject *
190
+ PYCAPI_COMPAT_STATIC_INLINE ( PyFrameObject * )
177
191
PyFrame_GetBack (PyFrameObject * frame )
178
192
{
179
- assert (frame != NULL );
180
- return (PyFrameObject * ) Py_XNewRef (frame -> f_back );
193
+ assert (frame != PYCAPI_COMPAT_NULL );
194
+ return PYCAPI_COMPAT_CAST (PyFrameObject * , Py_XNewRef (frame -> f_back ) );
181
195
}
182
196
#endif
183
197
184
198
#if !defined(PYPY_VERSION )
185
- static inline PyFrameObject *
199
+ PYCAPI_COMPAT_STATIC_INLINE ( PyFrameObject * )
186
200
_PyFrame_GetBackBorrow (PyFrameObject * frame )
187
201
{
188
- return (PyFrameObject * )_Py_XStealRef (PyFrame_GetBack (frame ));
202
+ return PYCAPI_COMPAT_CAST (PyFrameObject * ,
203
+ _Py_XStealRef (PyFrame_GetBack (frame )));
189
204
}
190
205
#endif
191
206
192
207
193
208
// bpo-39947 added PyThreadState_GetInterpreter() to Python 3.9.0a5
194
209
#if PY_VERSION_HEX < 0x030900A5
195
- static inline PyInterpreterState *
210
+ PYCAPI_COMPAT_STATIC_INLINE ( PyInterpreterState * )
196
211
PyThreadState_GetInterpreter (PyThreadState * tstate )
197
212
{
198
- assert (tstate != NULL );
213
+ assert (tstate != PYCAPI_COMPAT_NULL );
199
214
return tstate -> interp ;
200
215
}
201
216
#endif
202
217
203
218
204
219
// bpo-40429 added PyThreadState_GetFrame() to Python 3.9.0b1
205
220
#if PY_VERSION_HEX < 0x030900B1 && !defined(PYPY_VERSION )
206
- static inline PyFrameObject *
221
+ PYCAPI_COMPAT_STATIC_INLINE ( PyFrameObject * )
207
222
PyThreadState_GetFrame (PyThreadState * tstate )
208
223
{
209
- assert (tstate != NULL );
210
- return (PyFrameObject * ) Py_XNewRef (tstate -> frame );
224
+ assert (tstate != PYCAPI_COMPAT_NULL );
225
+ return PYCAPI_COMPAT_CAST (PyFrameObject * , Py_XNewRef (tstate -> frame ) );
211
226
}
212
227
#endif
213
228
214
229
#if !defined(PYPY_VERSION )
215
- static inline PyFrameObject *
230
+ PYCAPI_COMPAT_STATIC_INLINE ( PyFrameObject * )
216
231
_PyThreadState_GetFrameBorrow (PyThreadState * tstate )
217
232
{
218
- return (PyFrameObject * )_Py_XStealRef (PyThreadState_GetFrame (tstate ));
233
+ return PYCAPI_COMPAT_CAST (PyFrameObject * ,
234
+ _Py_XStealRef (PyThreadState_GetFrame (tstate )));
219
235
}
220
236
#endif
221
237
222
238
223
239
// bpo-39947 added PyInterpreterState_Get() to Python 3.9.0a5
224
240
#if PY_VERSION_HEX < 0x030900A5
225
- static inline PyInterpreterState *
241
+ PYCAPI_COMPAT_STATIC_INLINE ( PyInterpreterState * )
226
242
PyInterpreterState_Get (void )
227
243
{
228
244
PyThreadState * tstate ;
229
245
PyInterpreterState * interp ;
230
246
231
247
tstate = PyThreadState_GET ();
232
- if (tstate == NULL ) {
248
+ if (tstate == PYCAPI_COMPAT_NULL ) {
233
249
Py_FatalError ("GIL released (tstate is NULL)" );
234
250
}
235
251
interp = tstate -> interp ;
236
- if (interp == NULL ) {
252
+ if (interp == PYCAPI_COMPAT_NULL ) {
237
253
Py_FatalError ("no current interpreter" );
238
254
}
239
255
return interp ;
@@ -243,17 +259,18 @@ PyInterpreterState_Get(void)
243
259
244
260
// bpo-39947 added PyInterpreterState_Get() to Python 3.9.0a6
245
261
#if 0x030700A1 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x030900A6 && !defined(PYPY_VERSION )
246
- static inline uint64_t
262
+ PYCAPI_COMPAT_STATIC_INLINE ( uint64_t )
247
263
PyThreadState_GetID (PyThreadState * tstate )
248
264
{
249
- assert (tstate != NULL );
265
+ assert (tstate != PYCAPI_COMPAT_NULL );
250
266
return tstate -> id ;
251
267
}
252
268
#endif
253
269
254
270
// bpo-43760 added PyThreadState_EnterTracing() to Python 3.11.0a2
255
271
#if PY_VERSION_HEX < 0x030B00A2 && !defined(PYPY_VERSION )
256
- static inline void PyThreadState_EnterTracing (PyThreadState * tstate )
272
+ PYCAPI_COMPAT_STATIC_INLINE (void )
273
+ PyThreadState_EnterTracing (PyThreadState * tstate )
257
274
{
258
275
tstate -> tracing ++ ;
259
276
#if PY_VERSION_HEX >= 0x030A00A1
@@ -266,11 +283,12 @@ static inline void PyThreadState_EnterTracing(PyThreadState *tstate)
266
283
267
284
// bpo-43760 added PyThreadState_LeaveTracing() to Python 3.11.0a2
268
285
#if PY_VERSION_HEX < 0x030B00A2 && !defined(PYPY_VERSION )
269
- static inline void PyThreadState_LeaveTracing (PyThreadState * tstate )
286
+ PYCAPI_COMPAT_STATIC_INLINE (void )
287
+ PyThreadState_LeaveTracing (PyThreadState * tstate )
270
288
{
289
+ int use_tracing = (tstate -> c_tracefunc != PYCAPI_COMPAT_NULL
290
+ || tstate -> c_profilefunc != PYCAPI_COMPAT_NULL );
271
291
tstate -> tracing -- ;
272
- int use_tracing = (tstate -> c_tracefunc != NULL
273
- || tstate -> c_profilefunc != NULL );
274
292
#if PY_VERSION_HEX >= 0x030A00A1
275
293
tstate -> cframe -> use_tracing = use_tracing ;
276
294
#else
@@ -282,7 +300,7 @@ static inline void PyThreadState_LeaveTracing(PyThreadState *tstate)
282
300
283
301
// bpo-37194 added PyObject_CallNoArgs() to Python 3.9.0a1
284
302
#if PY_VERSION_HEX < 0x030900A1
285
- static inline PyObject *
303
+ PYCAPI_COMPAT_STATIC_INLINE ( PyObject * )
286
304
PyObject_CallNoArgs (PyObject * func )
287
305
{
288
306
return PyObject_CallFunctionObjArgs (func , NULL );
@@ -293,7 +311,7 @@ PyObject_CallNoArgs(PyObject *func)
293
311
// bpo-39245 made PyObject_CallOneArg() public (previously called
294
312
// _PyObject_CallOneArg) in Python 3.9.0a4
295
313
#if PY_VERSION_HEX < 0x030900A4
296
- static inline PyObject *
314
+ PYCAPI_COMPAT_STATIC_INLINE ( PyObject * )
297
315
PyObject_CallOneArg (PyObject * func , PyObject * arg )
298
316
{
299
317
return PyObject_CallFunctionObjArgs (func , arg , NULL );
@@ -303,12 +321,12 @@ PyObject_CallOneArg(PyObject *func, PyObject *arg)
303
321
304
322
// bpo-1635741 added PyModule_AddObjectRef() to Python 3.10.0a3
305
323
#if PY_VERSION_HEX < 0x030A00A3
306
- static inline int
307
- PyModule_AddObjectRef (PyObject * module , const char * name , PyObject * value )
324
+ PYCAPI_COMPAT_STATIC_INLINE ( int )
325
+ PyModule_AddObjectRef (PyObject * mod , const char * name , PyObject * value )
308
326
{
309
327
int res ;
310
328
Py_XINCREF (value );
311
- res = PyModule_AddObject (module , name , value );
329
+ res = PyModule_AddObject (mod , name , value );
312
330
if (res < 0 ) {
313
331
Py_XDECREF (value );
314
332
}
@@ -319,8 +337,8 @@ PyModule_AddObjectRef(PyObject *module, const char *name, PyObject *value)
319
337
320
338
// bpo-40024 added PyModule_AddType() to Python 3.9.0a5
321
339
#if PY_VERSION_HEX < 0x030900A5
322
- static inline int
323
- PyModule_AddType (PyObject * module , PyTypeObject * type )
340
+ PYCAPI_COMPAT_STATIC_INLINE ( int )
341
+ PyModule_AddType (PyObject * mod , PyTypeObject * type )
324
342
{
325
343
const char * name , * dot ;
326
344
@@ -330,21 +348,21 @@ PyModule_AddType(PyObject *module, PyTypeObject *type)
330
348
331
349
// inline _PyType_Name()
332
350
name = type -> tp_name ;
333
- assert (name != NULL );
351
+ assert (name != PYCAPI_COMPAT_NULL );
334
352
dot = strrchr (name , '.' );
335
- if (dot != NULL ) {
353
+ if (dot != PYCAPI_COMPAT_NULL ) {
336
354
name = dot + 1 ;
337
355
}
338
356
339
- return PyModule_AddObjectRef (module , name , ( PyObject * ) type );
357
+ return PyModule_AddObjectRef (mod , name , _PyObject_CAST ( type ) );
340
358
}
341
359
#endif
342
360
343
361
344
362
// bpo-40241 added PyObject_GC_IsTracked() to Python 3.9.0a6.
345
363
// bpo-4688 added _PyObject_GC_IS_TRACKED() to Python 2.7.0a2.
346
364
#if PY_VERSION_HEX < 0x030900A6 && !defined(PYPY_VERSION )
347
- static inline int
365
+ PYCAPI_COMPAT_STATIC_INLINE ( int )
348
366
PyObject_GC_IsTracked (PyObject * obj )
349
367
{
350
368
return (PyObject_IS_GC (obj ) && _PyObject_GC_IS_TRACKED (obj ));
@@ -354,17 +372,18 @@ PyObject_GC_IsTracked(PyObject* obj)
354
372
// bpo-40241 added PyObject_GC_IsFinalized() to Python 3.9.0a6.
355
373
// bpo-18112 added _PyGCHead_FINALIZED() to Python 3.4.0 final.
356
374
#if PY_VERSION_HEX < 0x030900A6 && PY_VERSION_HEX >= 0x030400F0 && !defined(PYPY_VERSION )
357
- static inline int
375
+ PYCAPI_COMPAT_STATIC_INLINE ( int )
358
376
PyObject_GC_IsFinalized (PyObject * obj )
359
377
{
360
- return (PyObject_IS_GC (obj ) && _PyGCHead_FINALIZED ((PyGC_Head * )(obj )- 1 ));
378
+ PyGC_Head * gc = PYCAPI_COMPAT_CAST (PyGC_Head * , obj ) - 1 ;
379
+ return (PyObject_IS_GC (obj ) && _PyGCHead_FINALIZED (gc ));
361
380
}
362
381
#endif
363
382
364
383
365
384
// bpo-39573 added Py_IS_TYPE() to Python 3.9.0a4
366
385
#if PY_VERSION_HEX < 0x030900A4 && !defined(Py_IS_TYPE )
367
- static inline int
386
+ PYCAPI_COMPAT_STATIC_INLINE ( int )
368
387
_Py_IS_TYPE (const PyObject * ob , const PyTypeObject * type ) {
369
388
return ob -> ob_type == type ;
370
389
}
@@ -382,11 +401,6 @@ _Py_IS_TYPE(const PyObject *ob, const PyTypeObject *type) {
382
401
#endif
383
402
384
403
385
- #ifdef PYTHONCAPI_COMPAT_MSC_INLINE
386
- # undef inline
387
- # undef PYTHONCAPI_COMPAT_MSC_INLINE
388
- #endif
389
-
390
404
#ifdef __cplusplus
391
405
}
392
406
#endif
0 commit comments