Skip to content

Commit 1bcdd49

Browse files
committed
Sync pythoncapi_compat.h
1 parent 4a17549 commit 1bcdd49

File tree

1 file changed

+125
-39
lines changed

1 file changed

+125
-39
lines changed

immutables/pythoncapi_compat.h

Lines changed: 125 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
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)
5166
static 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)
6277
static 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)
73110
static 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)
105177
static inline PyCodeObject*
106178
PyFrame_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

117186
static 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)
128195
static inline PyFrameObject*
129196
PyFrame_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)
139204
static 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)
161225
static inline PyFrameObject*
162226
PyThreadState_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)
172234
static 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)
204265
static inline uint64_t
205266
PyThreadState_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
236313
static 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)
267338
static inline int
268339
PyObject_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)
277348
static inline int
278349
PyObject_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

Comments
 (0)