Skip to content

Commit 1a539d7

Browse files
authored
Merge pull request #114 from vstinner/python311
Port to Python 3.11: use Py_SET_SIZE()
2 parents aef4880 + 5575c80 commit 1a539d7

File tree

2 files changed

+395
-1
lines changed

2 files changed

+395
-1
lines changed

src/snappy/pythoncapi_compat.h

Lines changed: 393 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,393 @@
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+
// Copyright Contributors to the pythoncapi_compat project.
6+
//
7+
// Homepage:
8+
// https://github.com/pythoncapi/pythoncapi_compat
9+
//
10+
// Latest version:
11+
// https://raw.githubusercontent.com/pythoncapi/pythoncapi_compat/master/pythoncapi_compat.h
12+
//
13+
// SPDX-License-Identifier: MIT
14+
15+
#ifndef PYTHONCAPI_COMPAT
16+
#define PYTHONCAPI_COMPAT
17+
18+
#ifdef __cplusplus
19+
extern "C" {
20+
#endif
21+
22+
#include <Python.h>
23+
#include "frameobject.h" // PyFrameObject, PyFrame_GetBack()
24+
25+
26+
// Compatibility with Visual Studio 2013 and older which don't support
27+
// the inline keyword in C (only in C++): use __inline instead.
28+
#if (defined(_MSC_VER) && _MSC_VER < 1900 \
29+
&& !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
33+
#endif
34+
35+
36+
// Cast argument to PyObject* type.
37+
#ifndef _PyObject_CAST
38+
# define _PyObject_CAST(op) ((PyObject*)(op))
39+
#endif
40+
#ifndef _PyObject_CAST_CONST
41+
# define _PyObject_CAST_CONST(op) ((const PyObject*)(op))
42+
#endif
43+
44+
45+
// bpo-42262 added Py_NewRef() to Python 3.10.0a3
46+
#if PY_VERSION_HEX < 0x030A00A3 && !defined(Py_NewRef)
47+
static inline PyObject* _Py_NewRef(PyObject *obj)
48+
{
49+
Py_INCREF(obj);
50+
return obj;
51+
}
52+
#define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
53+
#endif
54+
55+
56+
// bpo-42262 added Py_XNewRef() to Python 3.10.0a3
57+
#if PY_VERSION_HEX < 0x030A00A3 && !defined(Py_XNewRef)
58+
static inline PyObject* _Py_XNewRef(PyObject *obj)
59+
{
60+
Py_XINCREF(obj);
61+
return obj;
62+
}
63+
#define Py_XNewRef(obj) _Py_XNewRef(_PyObject_CAST(obj))
64+
#endif
65+
66+
67+
// See https://bugs.python.org/issue42522
68+
#if !defined(_Py_StealRef)
69+
static inline PyObject* __Py_StealRef(PyObject *obj)
70+
{
71+
Py_DECREF(obj);
72+
return obj;
73+
}
74+
#define _Py_StealRef(obj) __Py_StealRef(_PyObject_CAST(obj))
75+
#endif
76+
77+
78+
// See https://bugs.python.org/issue42522
79+
#if !defined(_Py_XStealRef)
80+
static inline PyObject* __Py_XStealRef(PyObject *obj)
81+
{
82+
Py_XDECREF(obj);
83+
return obj;
84+
}
85+
#define _Py_XStealRef(obj) __Py_XStealRef(_PyObject_CAST(obj))
86+
#endif
87+
88+
89+
// bpo-39573 added Py_SET_REFCNT() to Python 3.9.0a4
90+
#if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_REFCNT)
91+
static inline void _Py_SET_REFCNT(PyObject *ob, Py_ssize_t refcnt)
92+
{
93+
ob->ob_refcnt = refcnt;
94+
}
95+
#define Py_SET_REFCNT(ob, refcnt) _Py_SET_REFCNT(_PyObject_CAST(ob), refcnt)
96+
#endif
97+
98+
99+
// Py_SETREF() and Py_XSETREF() were added to Python 3.5.2.
100+
// It is excluded from the limited C API.
101+
#if (PY_VERSION_HEX < 0x03050200 && !defined(Py_SETREF)) && !defined(Py_LIMITED_API)
102+
#define Py_SETREF(op, op2) \
103+
do { \
104+
PyObject *_py_tmp = _PyObject_CAST(op); \
105+
(op) = (op2); \
106+
Py_DECREF(_py_tmp); \
107+
} while (0)
108+
109+
#define Py_XSETREF(op, op2) \
110+
do { \
111+
PyObject *_py_tmp = _PyObject_CAST(op); \
112+
(op) = (op2); \
113+
Py_XDECREF(_py_tmp); \
114+
} while (0)
115+
#endif
116+
117+
118+
// bpo-43753 added Py_Is(), Py_IsNone(), Py_IsTrue() and Py_IsFalse()
119+
// to Python 3.10.0b1.
120+
#if PY_VERSION_HEX < 0x030A00B1 && !defined(Py_Is)
121+
# define Py_Is(x, y) ((x) == (y))
122+
#endif
123+
#if PY_VERSION_HEX < 0x030A00B1 && !defined(Py_IsNone)
124+
# define Py_IsNone(x) Py_Is(x, Py_None)
125+
#endif
126+
#if PY_VERSION_HEX < 0x030A00B1 && !defined(Py_IsTrue)
127+
# define Py_IsTrue(x) Py_Is(x, Py_True)
128+
#endif
129+
#if PY_VERSION_HEX < 0x030A00B1 && !defined(Py_IsFalse)
130+
# define Py_IsFalse(x) Py_Is(x, Py_False)
131+
#endif
132+
133+
134+
// bpo-39573 added Py_SET_TYPE() to Python 3.9.0a4
135+
#if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_TYPE)
136+
static inline void
137+
_Py_SET_TYPE(PyObject *ob, PyTypeObject *type)
138+
{
139+
ob->ob_type = type;
140+
}
141+
#define Py_SET_TYPE(ob, type) _Py_SET_TYPE(_PyObject_CAST(ob), type)
142+
#endif
143+
144+
145+
// bpo-39573 added Py_SET_SIZE() to Python 3.9.0a4
146+
#if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_SIZE)
147+
static inline void
148+
_Py_SET_SIZE(PyVarObject *ob, Py_ssize_t size)
149+
{
150+
ob->ob_size = size;
151+
}
152+
#define Py_SET_SIZE(ob, size) _Py_SET_SIZE((PyVarObject*)(ob), size)
153+
#endif
154+
155+
156+
// bpo-40421 added PyFrame_GetCode() to Python 3.9.0b1
157+
#if PY_VERSION_HEX < 0x030900B1
158+
static inline PyCodeObject*
159+
PyFrame_GetCode(PyFrameObject *frame)
160+
{
161+
assert(frame != NULL);
162+
assert(frame->f_code != NULL);
163+
return (PyCodeObject*)Py_NewRef(frame->f_code);
164+
}
165+
#endif
166+
167+
static inline PyCodeObject*
168+
_PyFrame_GetCodeBorrow(PyFrameObject *frame)
169+
{
170+
return (PyCodeObject *)_Py_StealRef(PyFrame_GetCode(frame));
171+
}
172+
173+
174+
// bpo-40421 added PyFrame_GetCode() to Python 3.9.0b1
175+
#if PY_VERSION_HEX < 0x030900B1 && !defined(PYPY_VERSION)
176+
static inline PyFrameObject*
177+
PyFrame_GetBack(PyFrameObject *frame)
178+
{
179+
assert(frame != NULL);
180+
return (PyFrameObject*)Py_XNewRef(frame->f_back);
181+
}
182+
#endif
183+
184+
#if !defined(PYPY_VERSION)
185+
static inline PyFrameObject*
186+
_PyFrame_GetBackBorrow(PyFrameObject *frame)
187+
{
188+
return (PyFrameObject *)_Py_XStealRef(PyFrame_GetBack(frame));
189+
}
190+
#endif
191+
192+
193+
// bpo-39947 added PyThreadState_GetInterpreter() to Python 3.9.0a5
194+
#if PY_VERSION_HEX < 0x030900A5
195+
static inline PyInterpreterState *
196+
PyThreadState_GetInterpreter(PyThreadState *tstate)
197+
{
198+
assert(tstate != NULL);
199+
return tstate->interp;
200+
}
201+
#endif
202+
203+
204+
// bpo-40429 added PyThreadState_GetFrame() to Python 3.9.0b1
205+
#if PY_VERSION_HEX < 0x030900B1 && !defined(PYPY_VERSION)
206+
static inline PyFrameObject*
207+
PyThreadState_GetFrame(PyThreadState *tstate)
208+
{
209+
assert(tstate != NULL);
210+
return (PyFrameObject *)Py_XNewRef(tstate->frame);
211+
}
212+
#endif
213+
214+
#if !defined(PYPY_VERSION)
215+
static inline PyFrameObject*
216+
_PyThreadState_GetFrameBorrow(PyThreadState *tstate)
217+
{
218+
return (PyFrameObject *)_Py_XStealRef(PyThreadState_GetFrame(tstate));
219+
}
220+
#endif
221+
222+
223+
// bpo-39947 added PyInterpreterState_Get() to Python 3.9.0a5
224+
#if PY_VERSION_HEX < 0x030900A5
225+
static inline PyInterpreterState *
226+
PyInterpreterState_Get(void)
227+
{
228+
PyThreadState *tstate;
229+
PyInterpreterState *interp;
230+
231+
tstate = PyThreadState_GET();
232+
if (tstate == NULL) {
233+
Py_FatalError("GIL released (tstate is NULL)");
234+
}
235+
interp = tstate->interp;
236+
if (interp == NULL) {
237+
Py_FatalError("no current interpreter");
238+
}
239+
return interp;
240+
}
241+
#endif
242+
243+
244+
// bpo-39947 added PyInterpreterState_Get() to Python 3.9.0a6
245+
#if 0x030700A1 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x030900A6 && !defined(PYPY_VERSION)
246+
static inline uint64_t
247+
PyThreadState_GetID(PyThreadState *tstate)
248+
{
249+
assert(tstate != NULL);
250+
return tstate->id;
251+
}
252+
#endif
253+
254+
// bpo-43760 added PyThreadState_EnterTracing() to Python 3.11.0a2
255+
#if PY_VERSION_HEX < 0x030B00A2 && !defined(PYPY_VERSION)
256+
static inline void PyThreadState_EnterTracing(PyThreadState *tstate)
257+
{
258+
tstate->tracing++;
259+
#if PY_VERSION_HEX >= 0x030A00A1
260+
tstate->cframe->use_tracing = 0;
261+
#else
262+
tstate->use_tracing = 0;
263+
#endif
264+
}
265+
#endif
266+
267+
// bpo-43760 added PyThreadState_LeaveTracing() to Python 3.11.0a2
268+
#if PY_VERSION_HEX < 0x030B00A2 && !defined(PYPY_VERSION)
269+
static inline void PyThreadState_LeaveTracing(PyThreadState *tstate)
270+
{
271+
tstate->tracing--;
272+
int use_tracing = (tstate->c_tracefunc != NULL
273+
|| tstate->c_profilefunc != NULL);
274+
#if PY_VERSION_HEX >= 0x030A00A1
275+
tstate->cframe->use_tracing = use_tracing;
276+
#else
277+
tstate->use_tracing = use_tracing;
278+
#endif
279+
}
280+
#endif
281+
282+
283+
// bpo-37194 added PyObject_CallNoArgs() to Python 3.9.0a1
284+
#if PY_VERSION_HEX < 0x030900A1
285+
static inline PyObject*
286+
PyObject_CallNoArgs(PyObject *func)
287+
{
288+
return PyObject_CallFunctionObjArgs(func, NULL);
289+
}
290+
#endif
291+
292+
293+
// bpo-39245 made PyObject_CallOneArg() public (previously called
294+
// _PyObject_CallOneArg) in Python 3.9.0a4
295+
#if PY_VERSION_HEX < 0x030900A4
296+
static inline PyObject*
297+
PyObject_CallOneArg(PyObject *func, PyObject *arg)
298+
{
299+
return PyObject_CallFunctionObjArgs(func, arg, NULL);
300+
}
301+
#endif
302+
303+
304+
// bpo-1635741 added PyModule_AddObjectRef() to Python 3.10.0a3
305+
#if PY_VERSION_HEX < 0x030A00A3
306+
static inline int
307+
PyModule_AddObjectRef(PyObject *module, const char *name, PyObject *value)
308+
{
309+
int res;
310+
Py_XINCREF(value);
311+
res = PyModule_AddObject(module, name, value);
312+
if (res < 0) {
313+
Py_XDECREF(value);
314+
}
315+
return res;
316+
}
317+
#endif
318+
319+
320+
// bpo-40024 added PyModule_AddType() to Python 3.9.0a5
321+
#if PY_VERSION_HEX < 0x030900A5
322+
static inline int
323+
PyModule_AddType(PyObject *module, PyTypeObject *type)
324+
{
325+
const char *name, *dot;
326+
327+
if (PyType_Ready(type) < 0) {
328+
return -1;
329+
}
330+
331+
// inline _PyType_Name()
332+
name = type->tp_name;
333+
assert(name != NULL);
334+
dot = strrchr(name, '.');
335+
if (dot != NULL) {
336+
name = dot + 1;
337+
}
338+
339+
return PyModule_AddObjectRef(module, name, (PyObject *)type);
340+
}
341+
#endif
342+
343+
344+
// bpo-40241 added PyObject_GC_IsTracked() to Python 3.9.0a6.
345+
// bpo-4688 added _PyObject_GC_IS_TRACKED() to Python 2.7.0a2.
346+
#if PY_VERSION_HEX < 0x030900A6 && !defined(PYPY_VERSION)
347+
static inline int
348+
PyObject_GC_IsTracked(PyObject* obj)
349+
{
350+
return (PyObject_IS_GC(obj) && _PyObject_GC_IS_TRACKED(obj));
351+
}
352+
#endif
353+
354+
// bpo-40241 added PyObject_GC_IsFinalized() to Python 3.9.0a6.
355+
// bpo-18112 added _PyGCHead_FINALIZED() to Python 3.4.0 final.
356+
#if PY_VERSION_HEX < 0x030900A6 && PY_VERSION_HEX >= 0x030400F0 && !defined(PYPY_VERSION)
357+
static inline int
358+
PyObject_GC_IsFinalized(PyObject *obj)
359+
{
360+
return (PyObject_IS_GC(obj) && _PyGCHead_FINALIZED((PyGC_Head *)(obj)-1));
361+
}
362+
#endif
363+
364+
365+
// bpo-39573 added Py_IS_TYPE() to Python 3.9.0a4
366+
#if PY_VERSION_HEX < 0x030900A4 && !defined(Py_IS_TYPE)
367+
static inline int
368+
_Py_IS_TYPE(const PyObject *ob, const PyTypeObject *type) {
369+
return ob->ob_type == type;
370+
}
371+
#define Py_IS_TYPE(ob, type) _Py_IS_TYPE(_PyObject_CAST_CONST(ob), type)
372+
#endif
373+
374+
375+
// Py_UNUSED() was added to Python 3.4.0b2.
376+
#if PY_VERSION_HEX < 0x030400B2 && !defined(Py_UNUSED)
377+
# if defined(__GNUC__) || defined(__clang__)
378+
# define Py_UNUSED(name) _unused_ ## name __attribute__((unused))
379+
# else
380+
# define Py_UNUSED(name) _unused_ ## name
381+
# endif
382+
#endif
383+
384+
385+
#ifdef PYTHONCAPI_COMPAT_MSC_INLINE
386+
# undef inline
387+
# undef PYTHONCAPI_COMPAT_MSC_INLINE
388+
#endif
389+
390+
#ifdef __cplusplus
391+
}
392+
#endif
393+
#endif // PYTHONCAPI_COMPAT

0 commit comments

Comments
 (0)