2828//
2929// Latest version:
3030// https://raw.githubusercontent.com/pythoncapi/pythoncapi_compat/master/pythoncapi_compat.h
31+ //
32+ // SPDX-License-Identifier: MIT
3133
3234#ifndef PYTHONCAPI_COMPAT
3335#define PYTHONCAPI_COMPAT
@@ -40,14 +42,27 @@ extern "C" {
4042#include "frameobject.h" // PyFrameObject, PyFrame_GetBack()
4143
4244
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+
4355// Cast argument to PyObject* type.
4456#ifndef _PyObject_CAST
4557# define _PyObject_CAST (op ) ((PyObject*)(op))
4658#endif
59+ #ifndef _PyObject_CAST_CONST
60+ # define _PyObject_CAST_CONST (op ) ((const PyObject*)(op))
61+ #endif
4762
4863
4964// bpo-42262 added Py_NewRef() to Python 3.10.0a3
50- #if PY_VERSION_HEX < 0x030a00A3 && !defined(Py_NewRef )
65+ #if PY_VERSION_HEX < 0x030A00A3 && !defined(Py_NewRef )
5166static inline PyObject * _Py_NewRef (PyObject * obj )
5267{
5368 Py_INCREF (obj );
@@ -58,7 +73,7 @@ static inline PyObject* _Py_NewRef(PyObject *obj)
5873
5974
6075// bpo-42262 added Py_XNewRef() to Python 3.10.0a3
61- #if PY_VERSION_HEX < 0x030a00A3 && !defined(Py_XNewRef )
76+ #if PY_VERSION_HEX < 0x030A00A3 && !defined(Py_XNewRef )
6277static inline PyObject * _Py_XNewRef (PyObject * obj )
6378{
6479 Py_XINCREF (obj );
@@ -68,13 +83,70 @@ static inline PyObject* _Py_XNewRef(PyObject *obj)
6883#endif
6984
7085
86+ // See https://bugs.python.org/issue42522
87+ #if !defined(_Py_StealRef )
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 )
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+
71108// bpo-39573 added Py_SET_REFCNT() to Python 3.9.0a4
72109#if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_REFCNT )
73110static inline void _Py_SET_REFCNT (PyObject * ob , Py_ssize_t refcnt )
74111{
75112 ob -> ob_refcnt = refcnt ;
76113}
77- #define Py_SET_REFCNT (ob , refcnt ) _Py_SET_REFCNT((PyObject*)(ob), refcnt)
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)
78150#endif
79151
80152
@@ -85,7 +157,7 @@ _Py_SET_TYPE(PyObject *ob, PyTypeObject *type)
85157{
86158 ob -> ob_type = type ;
87159}
88- #define Py_SET_TYPE (ob , type ) _Py_SET_TYPE((PyObject*) (ob), type)
160+ #define Py_SET_TYPE (ob , type ) _Py_SET_TYPE(_PyObject_CAST (ob), type)
89161#endif
90162
91163
@@ -105,44 +177,36 @@ _Py_SET_SIZE(PyVarObject *ob, Py_ssize_t size)
105177static inline PyCodeObject *
106178PyFrame_GetCode (PyFrameObject * frame )
107179{
108- PyCodeObject * code ;
109180 assert (frame != NULL );
110- code = frame -> f_code ;
111- assert (code != NULL );
112- Py_INCREF (code );
113- return code ;
181+ assert (frame -> f_code != NULL );
182+ return (PyCodeObject * )Py_NewRef (frame -> f_code );
114183}
115184#endif
116185
117186static inline PyCodeObject *
118187_PyFrame_GetCodeBorrow (PyFrameObject * frame )
119188{
120- PyCodeObject * code = PyFrame_GetCode (frame );
121- Py_DECREF (code );
122- return code ; // borrowed reference
189+ return (PyCodeObject * )_Py_StealRef (PyFrame_GetCode (frame ));
123190}
124191
125192
126193// bpo-40421 added PyFrame_GetCode() to Python 3.9.0b1
127- #if PY_VERSION_HEX < 0x030900B1
194+ #if PY_VERSION_HEX < 0x030900B1 && !defined( PYPY_VERSION )
128195static inline PyFrameObject *
129196PyFrame_GetBack (PyFrameObject * frame )
130197{
131- PyFrameObject * back ;
132198 assert (frame != NULL );
133- back = frame -> f_back ;
134- Py_XINCREF (back );
135- return back ;
199+ return (PyFrameObject * )Py_XNewRef (frame -> f_back );
136200}
137201#endif
138202
203+ #if !defined(PYPY_VERSION )
139204static inline PyFrameObject *
140205_PyFrame_GetBackBorrow (PyFrameObject * frame )
141206{
142- PyFrameObject * back = PyFrame_GetBack (frame );
143- Py_XDECREF (back );
144- return back ; // borrowed reference
207+ return (PyFrameObject * )_Py_XStealRef (PyFrame_GetBack (frame ));
145208}
209+ #endif
146210
147211
148212// bpo-39947 added PyThreadState_GetInterpreter() to Python 3.9.0a5
@@ -157,25 +221,22 @@ PyThreadState_GetInterpreter(PyThreadState *tstate)
157221
158222
159223// bpo-40429 added PyThreadState_GetFrame() to Python 3.9.0b1
160- #if PY_VERSION_HEX < 0x030900B1
224+ #if PY_VERSION_HEX < 0x030900B1 && !defined( PYPY_VERSION )
161225static inline PyFrameObject *
162226PyThreadState_GetFrame (PyThreadState * tstate )
163227{
164- PyFrameObject * frame ;
165228 assert (tstate != NULL );
166- frame = tstate -> frame ;
167- Py_XINCREF (frame );
168- return frame ;
229+ return (PyFrameObject * )Py_XNewRef (tstate -> frame );
169230}
170231#endif
171232
233+ #if !defined(PYPY_VERSION )
172234static inline PyFrameObject *
173235_PyThreadState_GetFrameBorrow (PyThreadState * tstate )
174236{
175- PyFrameObject * frame = PyThreadState_GetFrame (tstate );
176- Py_XDECREF (frame );
177- return frame ; // borrowed reference
237+ return (PyFrameObject * )_Py_XStealRef (PyThreadState_GetFrame (tstate ));
178238}
239+ #endif
179240
180241
181242// bpo-39947 added PyInterpreterState_Get() to Python 3.9.0a5
@@ -200,7 +261,7 @@ PyInterpreterState_Get(void)
200261
201262
202263// bpo-39947 added PyInterpreterState_Get() to Python 3.9.0a6
203- #if 0x030700A1 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x030900A6
264+ #if 0x030700A1 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x030900A6 && !defined( PYPY_VERSION )
204265static inline uint64_t
205266PyThreadState_GetID (PyThreadState * tstate )
206267{
@@ -231,6 +292,22 @@ PyObject_CallOneArg(PyObject *func, PyObject *arg)
231292#endif
232293
233294
295+ // bpo-1635741 added PyModule_AddObjectRef() to Python 3.10.0a3
296+ #if PY_VERSION_HEX < 0x030A00A3
297+ static inline int
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+
234311// bpo-40024 added PyModule_AddType() to Python 3.9.0a5
235312#if PY_VERSION_HEX < 0x030900A5
236313static inline int
@@ -250,20 +327,14 @@ PyModule_AddType(PyObject *module, PyTypeObject *type)
250327 name = dot + 1 ;
251328 }
252329
253- Py_INCREF (type );
254- if (PyModule_AddObject (module , name , (PyObject * )type ) < 0 ) {
255- Py_DECREF (type );
256- return -1 ;
257- }
258-
259- return 0 ;
330+ return PyModule_AddObjectRef (module , name , (PyObject * )type );
260331}
261332#endif
262333
263334
264335// bpo-40241 added PyObject_GC_IsTracked() to Python 3.9.0a6.
265336// bpo-4688 added _PyObject_GC_IS_TRACKED() to Python 2.7.0a2.
266- #if PY_VERSION_HEX < 0x030900A6
337+ #if PY_VERSION_HEX < 0x030900A6 && !defined( PYPY_VERSION )
267338static inline int
268339PyObject_GC_IsTracked (PyObject * obj )
269340{
@@ -273,7 +344,7 @@ PyObject_GC_IsTracked(PyObject* obj)
273344
274345// bpo-40241 added PyObject_GC_IsFinalized() to Python 3.9.0a6.
275346// bpo-18112 added _PyGCHead_FINALIZED() to Python 3.4.0 final.
276- #if PY_VERSION_HEX < 0x030900A6 && PY_VERSION_HEX >= 0x030400F0
347+ #if PY_VERSION_HEX < 0x030900A6 && PY_VERSION_HEX >= 0x030400F0 && !defined( PYPY_VERSION )
277348static inline int
278349PyObject_GC_IsFinalized (PyObject * obj )
279350{
@@ -288,10 +359,25 @@ static inline int
288359_Py_IS_TYPE (const PyObject * ob , const PyTypeObject * type ) {
289360 return ob -> ob_type == type ;
290361}
291- #define Py_IS_TYPE (ob , type ) _Py_IS_TYPE((const PyObject*) (ob), type)
362+ #define Py_IS_TYPE (ob , type ) _Py_IS_TYPE(_PyObject_CAST_CONST (ob), type)
292363#endif
293364
294365
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+
295381#ifdef __cplusplus
296382}
297383#endif
0 commit comments