Skip to content

Commit a0cca9f

Browse files
authored
Merge pull request #109 from vstinner/py_set_size
Use Py_SET_TYPE() and Py_SET_SIZE() for Python 3.10
2 parents b036a95 + c88b54d commit a0cca9f

2 files changed

Lines changed: 290 additions & 9 deletions

File tree

‎bitarray/_bitarray.c‎

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#define PY_SSIZE_T_CLEAN
1313
#include "Python.h"
14+
#include "pythoncapi_compat.h"
1415

1516
#if PY_MAJOR_VERSION >= 3
1617
#define IS_PY3K
@@ -159,15 +160,15 @@ resize(bitarrayobject *self, Py_ssize_t nbits)
159160
*/
160161
if (allocated >= newsize && newsize >= (allocated >> 1)) {
161162
assert(self->ob_item != NULL || newsize == 0);
162-
Py_SIZE(self) = newsize;
163+
Py_SET_SIZE(self, newsize);
163164
self->nbits = nbits;
164165
return 0;
165166
}
166167

167168
if (newsize == 0) {
168169
PyMem_FREE(self->ob_item);
169170
self->ob_item = NULL;
170-
Py_SIZE(self) = 0;
171+
Py_SET_SIZE(self, 0);
171172
self->allocated = 0;
172173
self->nbits = 0;
173174
return 0;
@@ -197,7 +198,7 @@ resize(bitarrayobject *self, Py_ssize_t nbits)
197198
PyErr_NoMemory();
198199
return -1;
199200
}
200-
Py_SIZE(self) = newsize;
201+
Py_SET_SIZE(self, newsize);
201202
self->allocated = new_allocated;
202203
self->nbits = nbits;
203204
return 0;
@@ -215,7 +216,7 @@ newbitarrayobject(PyTypeObject *type, Py_ssize_t nbits, int endian)
215216
if (obj == NULL)
216217
return NULL;
217218

218-
Py_SIZE(obj) = nbytes;
219+
Py_SET_SIZE(obj, nbytes);
219220
if (nbytes == 0) {
220221
obj->ob_item = NULL;
221222
}
@@ -3396,27 +3397,27 @@ init_bitarray(void)
33963397

33973398
if (PyType_Ready(&Bitarray_Type) < 0)
33983399
goto error;
3399-
Py_TYPE(&Bitarray_Type) = &PyType_Type;
3400+
Py_SET_TYPE(&Bitarray_Type, &PyType_Type);
34003401
Py_INCREF((PyObject *) &Bitarray_Type);
34013402
PyModule_AddObject(m, "bitarray", (PyObject *) &Bitarray_Type);
34023403

34033404
if (PyType_Ready(&DecodeTree_Type) < 0)
34043405
goto error;
3405-
Py_TYPE(&DecodeTree_Type) = &PyType_Type;
3406+
Py_SET_TYPE(&DecodeTree_Type, &PyType_Type);
34063407
Py_INCREF((PyObject *) &DecodeTree_Type);
34073408
PyModule_AddObject(m, "decodetree", (PyObject *) &DecodeTree_Type);
34083409

34093410
if (PyType_Ready(&DecodeIter_Type) < 0)
34103411
goto error;
3411-
Py_TYPE(&DecodeIter_Type) = &PyType_Type;
3412+
Py_SET_TYPE(&DecodeIter_Type, &PyType_Type);
34123413

34133414
if (PyType_Ready(&BitarrayIter_Type) < 0)
34143415
goto error;
3415-
Py_TYPE(&BitarrayIter_Type) = &PyType_Type;
3416+
Py_SET_TYPE(&BitarrayIter_Type, &PyType_Type);
34163417

34173418
if (PyType_Ready(&SearchIter_Type) < 0)
34183419
goto error;
3419-
Py_TYPE(&SearchIter_Type) = &PyType_Type;
3420+
Py_SET_TYPE(&SearchIter_Type, &PyType_Type);
34203421

34213422
PyModule_AddObject(m, "__version__",
34223423
Py_BuildValue("s", BITARRAY_VERSION));

‎bitarray/pythoncapi_compat.h‎

Lines changed: 280 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,280 @@
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+
//
6+
// Homepage:
7+
// https://github.com/pythoncapi/pythoncapi_compat
8+
//
9+
// Latest version:
10+
// https://raw.githubusercontent.com/pythoncapi/pythoncapi_compat/master/pythoncapi_compat.h
11+
//
12+
// SPDX-License-Identifier: MIT
13+
14+
#ifndef PYTHONCAPI_COMPAT
15+
#define PYTHONCAPI_COMPAT
16+
17+
#ifdef __cplusplus
18+
extern "C" {
19+
#endif
20+
21+
#include <Python.h>
22+
#include "frameobject.h" // PyFrameObject, PyFrame_GetBack()
23+
24+
25+
// Cast argument to PyObject* type.
26+
#ifndef _PyObject_CAST
27+
# define _PyObject_CAST(op) ((PyObject*)(op))
28+
#endif
29+
30+
31+
// bpo-42262 added Py_NewRef() to Python 3.10.0a3
32+
#if PY_VERSION_HEX < 0x030a00A3 && !defined(Py_NewRef)
33+
static inline PyObject* _Py_NewRef(PyObject *obj)
34+
{
35+
Py_INCREF(obj);
36+
return obj;
37+
}
38+
#define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
39+
#endif
40+
41+
42+
// bpo-42262 added Py_XNewRef() to Python 3.10.0a3
43+
#if PY_VERSION_HEX < 0x030a00A3 && !defined(Py_XNewRef)
44+
static inline PyObject* _Py_XNewRef(PyObject *obj)
45+
{
46+
Py_XINCREF(obj);
47+
return obj;
48+
}
49+
#define Py_XNewRef(obj) _Py_XNewRef(_PyObject_CAST(obj))
50+
#endif
51+
52+
53+
// bpo-39573 added Py_SET_REFCNT() to Python 3.9.0a4
54+
#if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_REFCNT)
55+
static inline void _Py_SET_REFCNT(PyObject *ob, Py_ssize_t refcnt)
56+
{
57+
ob->ob_refcnt = refcnt;
58+
}
59+
#define Py_SET_REFCNT(ob, refcnt) _Py_SET_REFCNT((PyObject*)(ob), refcnt)
60+
#endif
61+
62+
63+
// bpo-39573 added Py_SET_TYPE() to Python 3.9.0a4
64+
#if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_TYPE)
65+
static inline void
66+
_Py_SET_TYPE(PyObject *ob, PyTypeObject *type)
67+
{
68+
ob->ob_type = type;
69+
}
70+
#define Py_SET_TYPE(ob, type) _Py_SET_TYPE((PyObject*)(ob), type)
71+
#endif
72+
73+
74+
// bpo-39573 added Py_SET_SIZE() to Python 3.9.0a4
75+
#if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_SIZE)
76+
static inline void
77+
_Py_SET_SIZE(PyVarObject *ob, Py_ssize_t size)
78+
{
79+
ob->ob_size = size;
80+
}
81+
#define Py_SET_SIZE(ob, size) _Py_SET_SIZE((PyVarObject*)(ob), size)
82+
#endif
83+
84+
85+
// bpo-40421 added PyFrame_GetCode() to Python 3.9.0b1
86+
#if PY_VERSION_HEX < 0x030900B1
87+
static inline PyCodeObject*
88+
PyFrame_GetCode(PyFrameObject *frame)
89+
{
90+
PyCodeObject *code;
91+
assert(frame != NULL);
92+
code = frame->f_code;
93+
assert(code != NULL);
94+
Py_INCREF(code);
95+
return code;
96+
}
97+
#endif
98+
99+
static inline PyCodeObject*
100+
_PyFrame_GetCodeBorrow(PyFrameObject *frame)
101+
{
102+
PyCodeObject *code = PyFrame_GetCode(frame);
103+
Py_DECREF(code);
104+
return code; // borrowed reference
105+
}
106+
107+
108+
// bpo-40421 added PyFrame_GetCode() to Python 3.9.0b1
109+
#if PY_VERSION_HEX < 0x030900B1
110+
static inline PyFrameObject*
111+
PyFrame_GetBack(PyFrameObject *frame)
112+
{
113+
PyFrameObject *back;
114+
assert(frame != NULL);
115+
back = frame->f_back;
116+
Py_XINCREF(back);
117+
return back;
118+
}
119+
#endif
120+
121+
static inline PyFrameObject*
122+
_PyFrame_GetBackBorrow(PyFrameObject *frame)
123+
{
124+
PyFrameObject *back = PyFrame_GetBack(frame);
125+
Py_XDECREF(back);
126+
return back; // borrowed reference
127+
}
128+
129+
130+
// bpo-39947 added PyThreadState_GetInterpreter() to Python 3.9.0a5
131+
#if PY_VERSION_HEX < 0x030900A5
132+
static inline PyInterpreterState *
133+
PyThreadState_GetInterpreter(PyThreadState *tstate)
134+
{
135+
assert(tstate != NULL);
136+
return tstate->interp;
137+
}
138+
#endif
139+
140+
141+
// bpo-40429 added PyThreadState_GetFrame() to Python 3.9.0b1
142+
#if PY_VERSION_HEX < 0x030900B1
143+
static inline PyFrameObject*
144+
PyThreadState_GetFrame(PyThreadState *tstate)
145+
{
146+
PyFrameObject *frame;
147+
assert(tstate != NULL);
148+
frame = tstate->frame;
149+
Py_XINCREF(frame);
150+
return frame;
151+
}
152+
#endif
153+
154+
static inline PyFrameObject*
155+
_PyThreadState_GetFrameBorrow(PyThreadState *tstate)
156+
{
157+
PyFrameObject *frame = PyThreadState_GetFrame(tstate);
158+
Py_XDECREF(frame);
159+
return frame; // borrowed reference
160+
}
161+
162+
163+
// bpo-39947 added PyInterpreterState_Get() to Python 3.9.0a5
164+
#if PY_VERSION_HEX < 0x030900A5
165+
static inline PyInterpreterState *
166+
PyInterpreterState_Get(void)
167+
{
168+
PyThreadState *tstate;
169+
PyInterpreterState *interp;
170+
171+
tstate = PyThreadState_GET();
172+
if (tstate == NULL) {
173+
Py_FatalError("GIL released (tstate is NULL)");
174+
}
175+
interp = tstate->interp;
176+
if (interp == NULL) {
177+
Py_FatalError("no current interpreter");
178+
}
179+
return interp;
180+
}
181+
#endif
182+
183+
184+
// bpo-39947 added PyInterpreterState_Get() to Python 3.9.0a6
185+
#if 0x030700A1 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x030900A6
186+
static inline uint64_t
187+
PyThreadState_GetID(PyThreadState *tstate)
188+
{
189+
assert(tstate != NULL);
190+
return tstate->id;
191+
}
192+
#endif
193+
194+
195+
// bpo-37194 added PyObject_CallNoArgs() to Python 3.9.0a1
196+
#if PY_VERSION_HEX < 0x030900A1
197+
static inline PyObject*
198+
PyObject_CallNoArgs(PyObject *func)
199+
{
200+
return PyObject_CallFunctionObjArgs(func, NULL);
201+
}
202+
#endif
203+
204+
205+
// bpo-39245 made PyObject_CallOneArg() public (previously called
206+
// _PyObject_CallOneArg) in Python 3.9.0a4
207+
#if PY_VERSION_HEX < 0x030900A4
208+
static inline PyObject*
209+
PyObject_CallOneArg(PyObject *func, PyObject *arg)
210+
{
211+
return PyObject_CallFunctionObjArgs(func, arg, NULL);
212+
}
213+
#endif
214+
215+
216+
// bpo-40024 added PyModule_AddType() to Python 3.9.0a5
217+
#if PY_VERSION_HEX < 0x030900A5
218+
static inline int
219+
PyModule_AddType(PyObject *module, PyTypeObject *type)
220+
{
221+
const char *name, *dot;
222+
223+
if (PyType_Ready(type) < 0) {
224+
return -1;
225+
}
226+
227+
// inline _PyType_Name()
228+
name = type->tp_name;
229+
assert(name != NULL);
230+
dot = strrchr(name, '.');
231+
if (dot != NULL) {
232+
name = dot + 1;
233+
}
234+
235+
Py_INCREF(type);
236+
if (PyModule_AddObject(module, name, (PyObject *)type) < 0) {
237+
Py_DECREF(type);
238+
return -1;
239+
}
240+
241+
return 0;
242+
}
243+
#endif
244+
245+
246+
// bpo-40241 added PyObject_GC_IsTracked() to Python 3.9.0a6.
247+
// bpo-4688 added _PyObject_GC_IS_TRACKED() to Python 2.7.0a2.
248+
#if PY_VERSION_HEX < 0x030900A6
249+
static inline int
250+
PyObject_GC_IsTracked(PyObject* obj)
251+
{
252+
return (PyObject_IS_GC(obj) && _PyObject_GC_IS_TRACKED(obj));
253+
}
254+
#endif
255+
256+
// bpo-40241 added PyObject_GC_IsFinalized() to Python 3.9.0a6.
257+
// bpo-18112 added _PyGCHead_FINALIZED() to Python 3.4.0 final.
258+
#if PY_VERSION_HEX < 0x030900A6 && PY_VERSION_HEX >= 0x030400F0
259+
static inline int
260+
PyObject_GC_IsFinalized(PyObject *obj)
261+
{
262+
return (PyObject_IS_GC(obj) && _PyGCHead_FINALIZED((PyGC_Head *)(obj)-1));
263+
}
264+
#endif
265+
266+
267+
// bpo-39573 added Py_IS_TYPE() to Python 3.9.0a4
268+
#if PY_VERSION_HEX < 0x030900A4 && !defined(Py_IS_TYPE)
269+
static inline int
270+
_Py_IS_TYPE(const PyObject *ob, const PyTypeObject *type) {
271+
return ob->ob_type == type;
272+
}
273+
#define Py_IS_TYPE(ob, type) _Py_IS_TYPE((const PyObject*)(ob), type)
274+
#endif
275+
276+
277+
#ifdef __cplusplus
278+
}
279+
#endif
280+
#endif // PYTHONCAPI_COMPAT

0 commit comments

Comments
 (0)