4
4
// Copyright Contributors to the pythoncapi_compat project.
5
5
//
6
6
// Homepage:
7
- // https://github.com/pythoncapi /pythoncapi_compat
7
+ // https://github.com/python /pythoncapi_compat
8
8
//
9
9
// Latest version:
10
- // https://raw.githubusercontent.com/pythoncapi /pythoncapi_compat/master/pythoncapi_compat.h
10
+ // https://raw.githubusercontent.com/python /pythoncapi_compat/master/pythoncapi_compat.h
11
11
//
12
12
// SPDX-License-Identifier: 0BSD
13
13
@@ -26,27 +26,32 @@ extern "C" {
26
26
// the inline keyword in C (only in C++): use __inline instead.
27
27
#if (defined(_MSC_VER ) && _MSC_VER < 1900 \
28
28
&& !defined(__cplusplus ) && !defined(inline ))
29
- # define PYCAPI_COMPAT_INLINE (TYPE static __inline TYPE
29
+ # define PYCAPI_COMPAT_STATIC_INLINE (TYPE ) static __inline TYPE
30
30
#else
31
31
# define PYCAPI_COMPAT_STATIC_INLINE (TYPE ) static inline TYPE
32
32
#endif
33
33
34
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
35
+ // C++ compatibility: _Py_CAST() and _Py_NULL
36
+ #ifndef _Py_CAST
37
+ # ifdef __cplusplus
38
+ # define _Py_CAST (type , expr ) \
39
+ const_cast<type>(reinterpret_cast<const type>(expr))
40
+ # else
41
+ # define _Py_CAST (type , expr ) ((type)(expr))
42
+ # endif
43
+ #endif
44
+ #ifndef _Py_NULL
45
+ # ifdef __cplusplus
46
+ # define _Py_NULL nullptr
47
+ # else
48
+ # define _Py_NULL NULL
49
+ # endif
42
50
#endif
43
51
44
52
// Cast argument to PyObject* type.
45
53
#ifndef _PyObject_CAST
46
- # define _PyObject_CAST (op ) PYCAPI_COMPAT_CAST(PyObject*, op)
47
- #endif
48
- #ifndef _PyObject_CAST_CONST
49
- # define _PyObject_CAST_CONST (op ) PYCAPI_COMPAT_CAST(const PyObject*, op)
54
+ # define _PyObject_CAST (op ) _Py_CAST(PyObject*, op)
50
55
#endif
51
56
52
57
@@ -74,30 +79,6 @@ _Py_XNewRef(PyObject *obj)
74
79
#endif
75
80
76
81
77
- // See https://bugs.python.org/issue42522
78
- #if !defined(_Py_StealRef )
79
- PYCAPI_COMPAT_STATIC_INLINE (PyObject * )
80
- __Py_StealRef (PyObject * obj )
81
- {
82
- Py_DECREF (obj );
83
- return obj ;
84
- }
85
- #define _Py_StealRef (obj ) __Py_StealRef(_PyObject_CAST(obj))
86
- #endif
87
-
88
-
89
- // See https://bugs.python.org/issue42522
90
- #if !defined(_Py_XStealRef )
91
- PYCAPI_COMPAT_STATIC_INLINE (PyObject * )
92
- __Py_XStealRef (PyObject * obj )
93
- {
94
- Py_XDECREF (obj );
95
- return obj ;
96
- }
97
- #define _Py_XStealRef (obj ) __Py_XStealRef(_PyObject_CAST(obj))
98
- #endif
99
-
100
-
101
82
// bpo-39573 added Py_SET_REFCNT() to Python 3.9.0a4
102
83
#if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_REFCNT )
103
84
PYCAPI_COMPAT_STATIC_INLINE (void )
@@ -171,36 +152,95 @@ _Py_SET_SIZE(PyVarObject *ob, Py_ssize_t size)
171
152
PYCAPI_COMPAT_STATIC_INLINE (PyCodeObject * )
172
153
PyFrame_GetCode (PyFrameObject * frame )
173
154
{
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 ));
155
+ assert (frame != _Py_NULL );
156
+ assert (frame -> f_code != _Py_NULL );
157
+ return _Py_CAST (PyCodeObject * , Py_NewRef (frame -> f_code ));
177
158
}
178
159
#endif
179
160
180
161
PYCAPI_COMPAT_STATIC_INLINE (PyCodeObject * )
181
162
_PyFrame_GetCodeBorrow (PyFrameObject * frame )
182
163
{
183
- return PYCAPI_COMPAT_CAST (PyCodeObject * ,
184
- _Py_StealRef (PyFrame_GetCode (frame )));
164
+ PyCodeObject * code = PyFrame_GetCode (frame );
165
+ Py_DECREF (code );
166
+ return code ;
185
167
}
186
168
187
169
188
- // bpo-40421 added PyFrame_GetCode () to Python 3.9.0b1
170
+ // bpo-40421 added PyFrame_GetBack () to Python 3.9.0b1
189
171
#if PY_VERSION_HEX < 0x030900B1 && !defined(PYPY_VERSION )
190
172
PYCAPI_COMPAT_STATIC_INLINE (PyFrameObject * )
191
173
PyFrame_GetBack (PyFrameObject * frame )
192
174
{
193
- assert (frame != PYCAPI_COMPAT_NULL );
194
- return PYCAPI_COMPAT_CAST (PyFrameObject * , Py_XNewRef (frame -> f_back ));
175
+ assert (frame != _Py_NULL );
176
+ return _Py_CAST (PyFrameObject * , Py_XNewRef (frame -> f_back ));
195
177
}
196
178
#endif
197
179
198
180
#if !defined(PYPY_VERSION )
199
181
PYCAPI_COMPAT_STATIC_INLINE (PyFrameObject * )
200
182
_PyFrame_GetBackBorrow (PyFrameObject * frame )
201
183
{
202
- return PYCAPI_COMPAT_CAST (PyFrameObject * ,
203
- _Py_XStealRef (PyFrame_GetBack (frame )));
184
+ PyFrameObject * back = PyFrame_GetBack (frame );
185
+ Py_XDECREF (back );
186
+ return back ;
187
+ }
188
+ #endif
189
+
190
+
191
+ // bpo-40421 added PyFrame_GetLocals() to Python 3.11.0a7
192
+ #if PY_VERSION_HEX < 0x030B00A7 && !defined(PYPY_VERSION )
193
+ PYCAPI_COMPAT_STATIC_INLINE (PyObject * )
194
+ PyFrame_GetLocals (PyFrameObject * frame )
195
+ {
196
+ #if PY_VERSION_HEX >= 0x030400B1
197
+ if (PyFrame_FastToLocalsWithError (frame ) < 0 ) {
198
+ return NULL ;
199
+ }
200
+ #else
201
+ PyFrame_FastToLocals (frame );
202
+ #endif
203
+ return Py_NewRef (frame -> f_locals );
204
+ }
205
+ #endif
206
+
207
+
208
+ // bpo-40421 added PyFrame_GetGlobals() to Python 3.11.0a7
209
+ #if PY_VERSION_HEX < 0x030B00A7 && !defined(PYPY_VERSION )
210
+ PYCAPI_COMPAT_STATIC_INLINE (PyObject * )
211
+ PyFrame_GetGlobals (PyFrameObject * frame )
212
+ {
213
+ return Py_NewRef (frame -> f_globals );
214
+ }
215
+ #endif
216
+
217
+
218
+ // bpo-40421 added PyFrame_GetBuiltins() to Python 3.11.0a7
219
+ #if PY_VERSION_HEX < 0x030B00A7 && !defined(PYPY_VERSION )
220
+ PYCAPI_COMPAT_STATIC_INLINE (PyObject * )
221
+ PyFrame_GetBuiltins (PyFrameObject * frame )
222
+ {
223
+ return Py_NewRef (frame -> f_builtins );
224
+ }
225
+ #endif
226
+
227
+
228
+ // bpo-40421 added PyFrame_GetLasti() to Python 3.11.0b1
229
+ #if PY_VERSION_HEX < 0x030B00B1 && !defined(PYPY_VERSION )
230
+ PYCAPI_COMPAT_STATIC_INLINE (int )
231
+ PyFrame_GetLasti (PyFrameObject * frame )
232
+ {
233
+ #if PY_VERSION_HEX >= 0x030A00A7
234
+ // bpo-27129: Since Python 3.10.0a7, f_lasti is an instruction offset,
235
+ // not a bytes offset anymore. Python uses 16-bit "wordcode" (2 bytes)
236
+ // instructions.
237
+ if (frame -> f_lasti < 0 ) {
238
+ return -1 ;
239
+ }
240
+ return frame -> f_lasti * 2 ;
241
+ #else
242
+ return frame -> f_lasti ;
243
+ #endif
204
244
}
205
245
#endif
206
246
@@ -210,7 +250,7 @@ _PyFrame_GetBackBorrow(PyFrameObject *frame)
210
250
PYCAPI_COMPAT_STATIC_INLINE (PyInterpreterState * )
211
251
PyThreadState_GetInterpreter (PyThreadState * tstate )
212
252
{
213
- assert (tstate != PYCAPI_COMPAT_NULL );
253
+ assert (tstate != _Py_NULL );
214
254
return tstate -> interp ;
215
255
}
216
256
#endif
@@ -221,17 +261,18 @@ PyThreadState_GetInterpreter(PyThreadState *tstate)
221
261
PYCAPI_COMPAT_STATIC_INLINE (PyFrameObject * )
222
262
PyThreadState_GetFrame (PyThreadState * tstate )
223
263
{
224
- assert (tstate != PYCAPI_COMPAT_NULL );
225
- return PYCAPI_COMPAT_CAST (PyFrameObject * , Py_XNewRef (tstate -> frame ));
264
+ assert (tstate != _Py_NULL );
265
+ return _Py_CAST (PyFrameObject * , Py_XNewRef (tstate -> frame ));
226
266
}
227
267
#endif
228
268
229
269
#if !defined(PYPY_VERSION )
230
270
PYCAPI_COMPAT_STATIC_INLINE (PyFrameObject * )
231
271
_PyThreadState_GetFrameBorrow (PyThreadState * tstate )
232
272
{
233
- return PYCAPI_COMPAT_CAST (PyFrameObject * ,
234
- _Py_XStealRef (PyThreadState_GetFrame (tstate )));
273
+ PyFrameObject * frame = PyThreadState_GetFrame (tstate );
274
+ Py_XDECREF (frame );
275
+ return frame ;
235
276
}
236
277
#endif
237
278
@@ -245,11 +286,11 @@ PyInterpreterState_Get(void)
245
286
PyInterpreterState * interp ;
246
287
247
288
tstate = PyThreadState_GET ();
248
- if (tstate == PYCAPI_COMPAT_NULL ) {
289
+ if (tstate == _Py_NULL ) {
249
290
Py_FatalError ("GIL released (tstate is NULL)" );
250
291
}
251
292
interp = tstate -> interp ;
252
- if (interp == PYCAPI_COMPAT_NULL ) {
293
+ if (interp == _Py_NULL ) {
253
294
Py_FatalError ("no current interpreter" );
254
295
}
255
296
return interp ;
@@ -262,7 +303,7 @@ PyInterpreterState_Get(void)
262
303
PYCAPI_COMPAT_STATIC_INLINE (uint64_t )
263
304
PyThreadState_GetID (PyThreadState * tstate )
264
305
{
265
- assert (tstate != PYCAPI_COMPAT_NULL );
306
+ assert (tstate != _Py_NULL );
266
307
return tstate -> id ;
267
308
}
268
309
#endif
@@ -286,8 +327,8 @@ PyThreadState_EnterTracing(PyThreadState *tstate)
286
327
PYCAPI_COMPAT_STATIC_INLINE (void )
287
328
PyThreadState_LeaveTracing (PyThreadState * tstate )
288
329
{
289
- int use_tracing = (tstate -> c_tracefunc != PYCAPI_COMPAT_NULL
290
- || tstate -> c_profilefunc != PYCAPI_COMPAT_NULL );
330
+ int use_tracing = (tstate -> c_tracefunc != _Py_NULL
331
+ || tstate -> c_profilefunc != _Py_NULL );
291
332
tstate -> tracing -- ;
292
333
#if PY_VERSION_HEX >= 0x030A00A1
293
334
tstate -> cframe -> use_tracing = use_tracing ;
@@ -322,11 +363,11 @@ PyObject_CallOneArg(PyObject *func, PyObject *arg)
322
363
// bpo-1635741 added PyModule_AddObjectRef() to Python 3.10.0a3
323
364
#if PY_VERSION_HEX < 0x030A00A3
324
365
PYCAPI_COMPAT_STATIC_INLINE (int )
325
- PyModule_AddObjectRef (PyObject * mod , const char * name , PyObject * value )
366
+ PyModule_AddObjectRef (PyObject * module , const char * name , PyObject * value )
326
367
{
327
368
int res ;
328
369
Py_XINCREF (value );
329
- res = PyModule_AddObject (mod , name , value );
370
+ res = PyModule_AddObject (module , name , value );
330
371
if (res < 0 ) {
331
372
Py_XDECREF (value );
332
373
}
@@ -338,7 +379,7 @@ PyModule_AddObjectRef(PyObject *mod, const char *name, PyObject *value)
338
379
// bpo-40024 added PyModule_AddType() to Python 3.9.0a5
339
380
#if PY_VERSION_HEX < 0x030900A5
340
381
PYCAPI_COMPAT_STATIC_INLINE (int )
341
- PyModule_AddType (PyObject * mod , PyTypeObject * type )
382
+ PyModule_AddType (PyObject * module , PyTypeObject * type )
342
383
{
343
384
const char * name , * dot ;
344
385
@@ -348,13 +389,13 @@ PyModule_AddType(PyObject *mod, PyTypeObject *type)
348
389
349
390
// inline _PyType_Name()
350
391
name = type -> tp_name ;
351
- assert (name != PYCAPI_COMPAT_NULL );
392
+ assert (name != _Py_NULL );
352
393
dot = strrchr (name , '.' );
353
- if (dot != PYCAPI_COMPAT_NULL ) {
394
+ if (dot != _Py_NULL ) {
354
395
name = dot + 1 ;
355
396
}
356
397
357
- return PyModule_AddObjectRef (mod , name , _PyObject_CAST (type ));
398
+ return PyModule_AddObjectRef (module , name , _PyObject_CAST (type ));
358
399
}
359
400
#endif
360
401
@@ -375,7 +416,7 @@ PyObject_GC_IsTracked(PyObject* obj)
375
416
PYCAPI_COMPAT_STATIC_INLINE (int )
376
417
PyObject_GC_IsFinalized (PyObject * obj )
377
418
{
378
- PyGC_Head * gc = PYCAPI_COMPAT_CAST (PyGC_Head * , obj ) - 1 ;
419
+ PyGC_Head * gc = _Py_CAST (PyGC_Head * , obj ) - 1 ;
379
420
return (PyObject_IS_GC (obj ) && _PyGCHead_FINALIZED (gc ));
380
421
}
381
422
#endif
@@ -384,10 +425,59 @@ PyObject_GC_IsFinalized(PyObject *obj)
384
425
// bpo-39573 added Py_IS_TYPE() to Python 3.9.0a4
385
426
#if PY_VERSION_HEX < 0x030900A4 && !defined(Py_IS_TYPE )
386
427
PYCAPI_COMPAT_STATIC_INLINE (int )
387
- _Py_IS_TYPE (const PyObject * ob , const PyTypeObject * type ) {
388
- return ob -> ob_type == type ;
428
+ _Py_IS_TYPE (PyObject * ob , PyTypeObject * type ) {
429
+ return Py_TYPE (ob ) == type ;
430
+ }
431
+ #define Py_IS_TYPE (ob , type ) _Py_IS_TYPE(_PyObject_CAST(ob), type)
432
+ #endif
433
+
434
+
435
+ // bpo-46906 added PyFloat_Pack2() and PyFloat_Unpack2() to Python 3.11a7.
436
+ // bpo-11734 added _PyFloat_Pack2() and _PyFloat_Unpack2() to Python 3.6.0b1.
437
+ // Python 3.11a2 moved _PyFloat_Pack2() and _PyFloat_Unpack2() to the internal
438
+ // C API: Python 3.11a2-3.11a6 versions are not supported.
439
+ #if 0x030600B1 <= PY_VERSION_HEX && PY_VERSION_HEX <= 0x030B00A1 && !defined(PYPY_VERSION )
440
+ PYCAPI_COMPAT_STATIC_INLINE (int )
441
+ PyFloat_Pack2 (double x , char * p , int le )
442
+ { return _PyFloat_Pack2 (x , (unsigned char * )p , le ); }
443
+
444
+ PYCAPI_COMPAT_STATIC_INLINE (double )
445
+ PyFloat_Unpack2 (const char * p , int le )
446
+ { return _PyFloat_Unpack2 ((const unsigned char * )p , le ); }
447
+ #endif
448
+
449
+
450
+ // bpo-46906 added PyFloat_Pack4(), PyFloat_Pack8(), PyFloat_Unpack4() and
451
+ // PyFloat_Unpack8() to Python 3.11a7.
452
+ // Python 3.11a2 moved _PyFloat_Pack4(), _PyFloat_Pack8(), _PyFloat_Unpack4()
453
+ // and _PyFloat_Unpack8() to the internal C API: Python 3.11a2-3.11a6 versions
454
+ // are not supported.
455
+ #if PY_VERSION_HEX <= 0x030B00A1 && !defined(PYPY_VERSION )
456
+ PYCAPI_COMPAT_STATIC_INLINE (int )
457
+ PyFloat_Pack4 (double x , char * p , int le )
458
+ { return _PyFloat_Pack4 (x , (unsigned char * )p , le ); }
459
+
460
+ PYCAPI_COMPAT_STATIC_INLINE (int )
461
+ PyFloat_Pack8 (double x , char * p , int le )
462
+ { return _PyFloat_Pack8 (x , (unsigned char * )p , le ); }
463
+
464
+ PYCAPI_COMPAT_STATIC_INLINE (double )
465
+ PyFloat_Unpack4 (const char * p , int le )
466
+ { return _PyFloat_Unpack4 ((const unsigned char * )p , le ); }
467
+
468
+ PYCAPI_COMPAT_STATIC_INLINE (double )
469
+ PyFloat_Unpack8 (const char * p , int le )
470
+ { return _PyFloat_Unpack8 ((const unsigned char * )p , le ); }
471
+ #endif
472
+
473
+
474
+ // gh-92154 added PyCode_GetCode() to Python 3.11.0b1
475
+ #if PY_VERSION_HEX < 0x030B00B1 && !defined(PYPY_VERSION )
476
+ PYCAPI_COMPAT_STATIC_INLINE (PyObject * )
477
+ PyCode_GetCode (PyCodeObject * code )
478
+ {
479
+ return Py_NewRef (code -> co_code );
389
480
}
390
- #define Py_IS_TYPE (ob , type ) _Py_IS_TYPE(_PyObject_CAST_CONST(ob), type)
391
481
#endif
392
482
393
483
0 commit comments