From 20d8ace4d4bacf5fd5c4e804cb35f54400812259 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 3 May 2022 16:05:27 +0200 Subject: [PATCH] Use Python 3.11 _Py_CAST() macro Remove _Py_StealRef() and _Py_XStealRef() functions. --- pythoncapi_compat.h | 59 +++++++++++------------------ tests/test_pythoncapi_compat_cext.c | 30 --------------- 2 files changed, 22 insertions(+), 67 deletions(-) diff --git a/pythoncapi_compat.h b/pythoncapi_compat.h index 803ffc5..ad2db2e 100644 --- a/pythoncapi_compat.h +++ b/pythoncapi_compat.h @@ -33,17 +33,23 @@ extern "C" { // C++ compatibility +#ifndef _Py_CAST +# ifdef __cplusplus +# define _Py_CAST(type, expr) \ + const_cast(reinterpret_cast(expr)) +# else +# define _Py_CAST(type, expr) ((type)(expr)) +# endif +#endif #ifdef __cplusplus -# define PYCAPI_COMPAT_CAST(TYPE, EXPR) reinterpret_cast(EXPR) # define PYCAPI_COMPAT_NULL nullptr #else -# define PYCAPI_COMPAT_CAST(TYPE, EXPR) ((TYPE)(EXPR)) # define PYCAPI_COMPAT_NULL NULL #endif // Cast argument to PyObject* type. #ifndef _PyObject_CAST -# define _PyObject_CAST(op) PYCAPI_COMPAT_CAST(PyObject*, op) +# define _PyObject_CAST(op) _Py_CAST(PyObject*, op) #endif @@ -71,30 +77,6 @@ _Py_XNewRef(PyObject *obj) #endif -// See https://bugs.python.org/issue42522 -#if !defined(_Py_StealRef) -PYCAPI_COMPAT_STATIC_INLINE(PyObject*) -__Py_StealRef(PyObject *obj) -{ - Py_DECREF(obj); - return obj; -} -#define _Py_StealRef(obj) __Py_StealRef(_PyObject_CAST(obj)) -#endif - - -// See https://bugs.python.org/issue42522 -#if !defined(_Py_XStealRef) -PYCAPI_COMPAT_STATIC_INLINE(PyObject*) -__Py_XStealRef(PyObject *obj) -{ - Py_XDECREF(obj); - return obj; -} -#define _Py_XStealRef(obj) __Py_XStealRef(_PyObject_CAST(obj)) -#endif - - // bpo-39573 added Py_SET_REFCNT() to Python 3.9.0a4 #if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_REFCNT) PYCAPI_COMPAT_STATIC_INLINE(void) @@ -170,15 +152,16 @@ PyFrame_GetCode(PyFrameObject *frame) { assert(frame != PYCAPI_COMPAT_NULL); assert(frame->f_code != PYCAPI_COMPAT_NULL); - return PYCAPI_COMPAT_CAST(PyCodeObject*, Py_NewRef(frame->f_code)); + return _Py_CAST(PyCodeObject*, Py_NewRef(frame->f_code)); } #endif PYCAPI_COMPAT_STATIC_INLINE(PyCodeObject*) _PyFrame_GetCodeBorrow(PyFrameObject *frame) { - return PYCAPI_COMPAT_CAST(PyCodeObject *, - _Py_StealRef(PyFrame_GetCode(frame))); + PyCodeObject *code = PyFrame_GetCode(frame); + Py_DECREF(code); + return code; } @@ -188,7 +171,7 @@ PYCAPI_COMPAT_STATIC_INLINE(PyFrameObject*) PyFrame_GetBack(PyFrameObject *frame) { assert(frame != PYCAPI_COMPAT_NULL); - return PYCAPI_COMPAT_CAST(PyFrameObject*, Py_XNewRef(frame->f_back)); + return _Py_CAST(PyFrameObject*, Py_XNewRef(frame->f_back)); } #endif @@ -196,8 +179,9 @@ PyFrame_GetBack(PyFrameObject *frame) PYCAPI_COMPAT_STATIC_INLINE(PyFrameObject*) _PyFrame_GetBackBorrow(PyFrameObject *frame) { - return PYCAPI_COMPAT_CAST(PyFrameObject *, - _Py_XStealRef(PyFrame_GetBack(frame))); + PyFrameObject *back = PyFrame_GetBack(frame); + Py_XDECREF(back); + return back; } #endif @@ -276,7 +260,7 @@ PYCAPI_COMPAT_STATIC_INLINE(PyFrameObject*) PyThreadState_GetFrame(PyThreadState *tstate) { assert(tstate != PYCAPI_COMPAT_NULL); - return PYCAPI_COMPAT_CAST(PyFrameObject *, Py_XNewRef(tstate->frame)); + return _Py_CAST(PyFrameObject *, Py_XNewRef(tstate->frame)); } #endif @@ -284,8 +268,9 @@ PyThreadState_GetFrame(PyThreadState *tstate) PYCAPI_COMPAT_STATIC_INLINE(PyFrameObject*) _PyThreadState_GetFrameBorrow(PyThreadState *tstate) { - return PYCAPI_COMPAT_CAST(PyFrameObject*, - _Py_XStealRef(PyThreadState_GetFrame(tstate))); + PyFrameObject *frame = PyThreadState_GetFrame(tstate); + Py_XDECREF(frame); + return frame; } #endif @@ -429,7 +414,7 @@ PyObject_GC_IsTracked(PyObject* obj) PYCAPI_COMPAT_STATIC_INLINE(int) PyObject_GC_IsFinalized(PyObject *obj) { - PyGC_Head *gc = PYCAPI_COMPAT_CAST(PyGC_Head *, obj) - 1; + PyGC_Head *gc = _Py_CAST(PyGC_Head*, obj) - 1; return (PyObject_IS_GC(obj) && _PyGCHead_FINALIZED(gc)); } #endif diff --git a/tests/test_pythoncapi_compat_cext.c b/tests/test_pythoncapi_compat_cext.c index ac5408a..ab369e5 100644 --- a/tests/test_pythoncapi_compat_cext.c +++ b/tests/test_pythoncapi_compat_cext.c @@ -130,35 +130,6 @@ test_py_is(PyObject *Py_UNUSED(module), PyObject* Py_UNUSED(ignored)) } -static PyObject * -test_steal_ref(PyObject *Py_UNUSED(module), PyObject* Py_UNUSED(ignored)) -{ - PyObject *obj = PyList_New(0); - if (obj == NULL) { - return NULL; - } - Py_ssize_t refcnt = Py_REFCNT(obj); - - // _Py_StealRef() - Py_INCREF(obj); - PyObject *ref = _Py_StealRef(obj); - assert(ref == obj); - assert(Py_REFCNT(obj) == refcnt); - - // _Py_XStealRef() - Py_INCREF(obj); - PyObject *xref = _Py_XStealRef(obj); - assert(xref == obj); - assert(Py_REFCNT(obj) == refcnt); - - assert(_Py_XStealRef(NULL) == NULL); - - assert(Py_REFCNT(obj) == refcnt); - Py_DECREF(obj); - Py_RETURN_NONE; -} - - #if !defined(PYPY_VERSION) static PyObject * test_frame(PyObject *Py_UNUSED(module), PyObject* Py_UNUSED(ignored)) @@ -516,7 +487,6 @@ test_code(PyObject *Py_UNUSED(module), PyObject* Py_UNUSED(ignored)) static struct PyMethodDef methods[] = { {"test_object", test_object, METH_NOARGS, NULL}, {"test_py_is", test_py_is, METH_NOARGS, NULL}, - {"test_steal_ref", test_steal_ref, METH_NOARGS, NULL}, #if !defined(PYPY_VERSION) {"test_frame", test_frame, METH_NOARGS, NULL}, #endif