Skip to content

Commit c9764f5

Browse files
authored
Use Python 3.11 _Py_CAST() macro (#35)
Remove _Py_StealRef() and _Py_XStealRef() functions.
1 parent 9267d9a commit c9764f5

File tree

2 files changed

+22
-67
lines changed

2 files changed

+22
-67
lines changed

pythoncapi_compat.h

Lines changed: 22 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -33,17 +33,23 @@ extern "C" {
3333

3434

3535
// C++ compatibility
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
3644
#ifdef __cplusplus
37-
# define PYCAPI_COMPAT_CAST(TYPE, EXPR) reinterpret_cast<TYPE>(EXPR)
3845
# define PYCAPI_COMPAT_NULL nullptr
3946
#else
40-
# define PYCAPI_COMPAT_CAST(TYPE, EXPR) ((TYPE)(EXPR))
4147
# define PYCAPI_COMPAT_NULL NULL
4248
#endif
4349

4450
// Cast argument to PyObject* type.
4551
#ifndef _PyObject_CAST
46-
# define _PyObject_CAST(op) PYCAPI_COMPAT_CAST(PyObject*, op)
52+
# define _PyObject_CAST(op) _Py_CAST(PyObject*, op)
4753
#endif
4854

4955

@@ -71,30 +77,6 @@ _Py_XNewRef(PyObject *obj)
7177
#endif
7278

7379

74-
// See https://bugs.python.org/issue42522
75-
#if !defined(_Py_StealRef)
76-
PYCAPI_COMPAT_STATIC_INLINE(PyObject*)
77-
__Py_StealRef(PyObject *obj)
78-
{
79-
Py_DECREF(obj);
80-
return obj;
81-
}
82-
#define _Py_StealRef(obj) __Py_StealRef(_PyObject_CAST(obj))
83-
#endif
84-
85-
86-
// See https://bugs.python.org/issue42522
87-
#if !defined(_Py_XStealRef)
88-
PYCAPI_COMPAT_STATIC_INLINE(PyObject*)
89-
__Py_XStealRef(PyObject *obj)
90-
{
91-
Py_XDECREF(obj);
92-
return obj;
93-
}
94-
#define _Py_XStealRef(obj) __Py_XStealRef(_PyObject_CAST(obj))
95-
#endif
96-
97-
9880
// bpo-39573 added Py_SET_REFCNT() to Python 3.9.0a4
9981
#if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_REFCNT)
10082
PYCAPI_COMPAT_STATIC_INLINE(void)
@@ -170,15 +152,16 @@ PyFrame_GetCode(PyFrameObject *frame)
170152
{
171153
assert(frame != PYCAPI_COMPAT_NULL);
172154
assert(frame->f_code != PYCAPI_COMPAT_NULL);
173-
return PYCAPI_COMPAT_CAST(PyCodeObject*, Py_NewRef(frame->f_code));
155+
return _Py_CAST(PyCodeObject*, Py_NewRef(frame->f_code));
174156
}
175157
#endif
176158

177159
PYCAPI_COMPAT_STATIC_INLINE(PyCodeObject*)
178160
_PyFrame_GetCodeBorrow(PyFrameObject *frame)
179161
{
180-
return PYCAPI_COMPAT_CAST(PyCodeObject *,
181-
_Py_StealRef(PyFrame_GetCode(frame)));
162+
PyCodeObject *code = PyFrame_GetCode(frame);
163+
Py_DECREF(code);
164+
return code;
182165
}
183166

184167

@@ -188,16 +171,17 @@ PYCAPI_COMPAT_STATIC_INLINE(PyFrameObject*)
188171
PyFrame_GetBack(PyFrameObject *frame)
189172
{
190173
assert(frame != PYCAPI_COMPAT_NULL);
191-
return PYCAPI_COMPAT_CAST(PyFrameObject*, Py_XNewRef(frame->f_back));
174+
return _Py_CAST(PyFrameObject*, Py_XNewRef(frame->f_back));
192175
}
193176
#endif
194177

195178
#if !defined(PYPY_VERSION)
196179
PYCAPI_COMPAT_STATIC_INLINE(PyFrameObject*)
197180
_PyFrame_GetBackBorrow(PyFrameObject *frame)
198181
{
199-
return PYCAPI_COMPAT_CAST(PyFrameObject *,
200-
_Py_XStealRef(PyFrame_GetBack(frame)));
182+
PyFrameObject *back = PyFrame_GetBack(frame);
183+
Py_XDECREF(back);
184+
return back;
201185
}
202186
#endif
203187

@@ -276,16 +260,17 @@ PYCAPI_COMPAT_STATIC_INLINE(PyFrameObject*)
276260
PyThreadState_GetFrame(PyThreadState *tstate)
277261
{
278262
assert(tstate != PYCAPI_COMPAT_NULL);
279-
return PYCAPI_COMPAT_CAST(PyFrameObject *, Py_XNewRef(tstate->frame));
263+
return _Py_CAST(PyFrameObject *, Py_XNewRef(tstate->frame));
280264
}
281265
#endif
282266

283267
#if !defined(PYPY_VERSION)
284268
PYCAPI_COMPAT_STATIC_INLINE(PyFrameObject*)
285269
_PyThreadState_GetFrameBorrow(PyThreadState *tstate)
286270
{
287-
return PYCAPI_COMPAT_CAST(PyFrameObject*,
288-
_Py_XStealRef(PyThreadState_GetFrame(tstate)));
271+
PyFrameObject *frame = PyThreadState_GetFrame(tstate);
272+
Py_XDECREF(frame);
273+
return frame;
289274
}
290275
#endif
291276

@@ -429,7 +414,7 @@ PyObject_GC_IsTracked(PyObject* obj)
429414
PYCAPI_COMPAT_STATIC_INLINE(int)
430415
PyObject_GC_IsFinalized(PyObject *obj)
431416
{
432-
PyGC_Head *gc = PYCAPI_COMPAT_CAST(PyGC_Head *, obj) - 1;
417+
PyGC_Head *gc = _Py_CAST(PyGC_Head*, obj) - 1;
433418
return (PyObject_IS_GC(obj) && _PyGCHead_FINALIZED(gc));
434419
}
435420
#endif

tests/test_pythoncapi_compat_cext.c

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -130,35 +130,6 @@ test_py_is(PyObject *Py_UNUSED(module), PyObject* Py_UNUSED(ignored))
130130
}
131131

132132

133-
static PyObject *
134-
test_steal_ref(PyObject *Py_UNUSED(module), PyObject* Py_UNUSED(ignored))
135-
{
136-
PyObject *obj = PyList_New(0);
137-
if (obj == NULL) {
138-
return NULL;
139-
}
140-
Py_ssize_t refcnt = Py_REFCNT(obj);
141-
142-
// _Py_StealRef()
143-
Py_INCREF(obj);
144-
PyObject *ref = _Py_StealRef(obj);
145-
assert(ref == obj);
146-
assert(Py_REFCNT(obj) == refcnt);
147-
148-
// _Py_XStealRef()
149-
Py_INCREF(obj);
150-
PyObject *xref = _Py_XStealRef(obj);
151-
assert(xref == obj);
152-
assert(Py_REFCNT(obj) == refcnt);
153-
154-
assert(_Py_XStealRef(NULL) == NULL);
155-
156-
assert(Py_REFCNT(obj) == refcnt);
157-
Py_DECREF(obj);
158-
Py_RETURN_NONE;
159-
}
160-
161-
162133
#if !defined(PYPY_VERSION)
163134
static PyObject *
164135
test_frame(PyObject *Py_UNUSED(module), PyObject* Py_UNUSED(ignored))
@@ -516,7 +487,6 @@ test_code(PyObject *Py_UNUSED(module), PyObject* Py_UNUSED(ignored))
516487
static struct PyMethodDef methods[] = {
517488
{"test_object", test_object, METH_NOARGS, NULL},
518489
{"test_py_is", test_py_is, METH_NOARGS, NULL},
519-
{"test_steal_ref", test_steal_ref, METH_NOARGS, NULL},
520490
#if !defined(PYPY_VERSION)
521491
{"test_frame", test_frame, METH_NOARGS, NULL},
522492
#endif

0 commit comments

Comments
 (0)