Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use reinterpret_cast and nullptr in pythoncapi_compat.h #3237

Merged
merged 1 commit into from
Feb 10, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
125 changes: 70 additions & 55 deletions src/core/lib/pythoncapi_compat.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,24 +27,34 @@ extern "C" {
// the inline keyword in C (only in C++): use __inline instead.
#if (defined(_MSC_VER) && _MSC_VER < 1900 \
&& !defined(__cplusplus) && !defined(inline))
# define inline __inline
# define PYTHONCAPI_COMPAT_MSC_INLINE
// These two macros are undefined at the end of this file
# define PYCAPI_COMPAT_INLINE(TYPE static __inline TYPE
#else
# define PYCAPI_COMPAT_STATIC_INLINE(TYPE) static inline TYPE
#endif


// C++ compatibility
#ifdef __cplusplus
# define PYCAPI_COMPAT_CAST(TYPE, EXPR) reinterpret_cast<TYPE>(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) ((PyObject*)(op))
# define _PyObject_CAST(op) PYCAPI_COMPAT_CAST(PyObject*, op)
#endif
#ifndef _PyObject_CAST_CONST
# define _PyObject_CAST_CONST(op) ((const PyObject*)(op))
# define _PyObject_CAST_CONST(op) PYCAPI_COMPAT_CAST(const PyObject*, op)
#endif


// bpo-42262 added Py_NewRef() to Python 3.10.0a3
#if PY_VERSION_HEX < 0x030A00A3 && !defined(Py_NewRef)
static inline PyObject* _Py_NewRef(PyObject *obj)
PYCAPI_COMPAT_STATIC_INLINE(PyObject*)
_Py_NewRef(PyObject *obj)
{
Py_INCREF(obj);
return obj;
Expand All @@ -55,7 +65,8 @@ static inline PyObject* _Py_NewRef(PyObject *obj)

// bpo-42262 added Py_XNewRef() to Python 3.10.0a3
#if PY_VERSION_HEX < 0x030A00A3 && !defined(Py_XNewRef)
static inline PyObject* _Py_XNewRef(PyObject *obj)
PYCAPI_COMPAT_STATIC_INLINE(PyObject*)
_Py_XNewRef(PyObject *obj)
{
Py_XINCREF(obj);
return obj;
Expand All @@ -66,7 +77,8 @@ static inline PyObject* _Py_XNewRef(PyObject *obj)

// See https://bugs.python.org/issue42522
#if !defined(_Py_StealRef)
static inline PyObject* __Py_StealRef(PyObject *obj)
PYCAPI_COMPAT_STATIC_INLINE(PyObject*)
__Py_StealRef(PyObject *obj)
{
Py_DECREF(obj);
return obj;
Expand All @@ -77,7 +89,8 @@ static inline PyObject* __Py_StealRef(PyObject *obj)

// See https://bugs.python.org/issue42522
#if !defined(_Py_XStealRef)
static inline PyObject* __Py_XStealRef(PyObject *obj)
PYCAPI_COMPAT_STATIC_INLINE(PyObject*)
__Py_XStealRef(PyObject *obj)
{
Py_XDECREF(obj);
return obj;
Expand All @@ -88,7 +101,8 @@ static inline PyObject* __Py_XStealRef(PyObject *obj)

// bpo-39573 added Py_SET_REFCNT() to Python 3.9.0a4
#if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_REFCNT)
static inline void _Py_SET_REFCNT(PyObject *ob, Py_ssize_t refcnt)
PYCAPI_COMPAT_STATIC_INLINE(void)
_Py_SET_REFCNT(PyObject *ob, Py_ssize_t refcnt)
{
ob->ob_refcnt = refcnt;
}
Expand Down Expand Up @@ -133,7 +147,7 @@ static inline void _Py_SET_REFCNT(PyObject *ob, Py_ssize_t refcnt)

// bpo-39573 added Py_SET_TYPE() to Python 3.9.0a4
#if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_TYPE)
static inline void
PYCAPI_COMPAT_STATIC_INLINE(void)
_Py_SET_TYPE(PyObject *ob, PyTypeObject *type)
{
ob->ob_type = type;
Expand All @@ -144,7 +158,7 @@ _Py_SET_TYPE(PyObject *ob, PyTypeObject *type)

// bpo-39573 added Py_SET_SIZE() to Python 3.9.0a4
#if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_SIZE)
static inline void
PYCAPI_COMPAT_STATIC_INLINE(void)
_Py_SET_SIZE(PyVarObject *ob, Py_ssize_t size)
{
ob->ob_size = size;
Expand All @@ -155,85 +169,88 @@ _Py_SET_SIZE(PyVarObject *ob, Py_ssize_t size)

// bpo-40421 added PyFrame_GetCode() to Python 3.9.0b1
#if PY_VERSION_HEX < 0x030900B1
static inline PyCodeObject*
PYCAPI_COMPAT_STATIC_INLINE(PyCodeObject*)
PyFrame_GetCode(PyFrameObject *frame)
{
assert(frame != NULL);
assert(frame->f_code != NULL);
return (PyCodeObject*)Py_NewRef(frame->f_code);
assert(frame != PYCAPI_COMPAT_NULL);
assert(frame->f_code != PYCAPI_COMPAT_NULL);
return PYCAPI_COMPAT_CAST(PyCodeObject*, Py_NewRef(frame->f_code));
}
#endif

static inline PyCodeObject*
PYCAPI_COMPAT_STATIC_INLINE(PyCodeObject*)
_PyFrame_GetCodeBorrow(PyFrameObject *frame)
{
return (PyCodeObject *)_Py_StealRef(PyFrame_GetCode(frame));
return PYCAPI_COMPAT_CAST(PyCodeObject *,
_Py_StealRef(PyFrame_GetCode(frame)));
}


// bpo-40421 added PyFrame_GetCode() to Python 3.9.0b1
#if PY_VERSION_HEX < 0x030900B1 && !defined(PYPY_VERSION)
static inline PyFrameObject*
PYCAPI_COMPAT_STATIC_INLINE(PyFrameObject*)
PyFrame_GetBack(PyFrameObject *frame)
{
assert(frame != NULL);
return (PyFrameObject*)Py_XNewRef(frame->f_back);
assert(frame != PYCAPI_COMPAT_NULL);
return PYCAPI_COMPAT_CAST(PyFrameObject*, Py_XNewRef(frame->f_back));
}
#endif

#if !defined(PYPY_VERSION)
static inline PyFrameObject*
PYCAPI_COMPAT_STATIC_INLINE(PyFrameObject*)
_PyFrame_GetBackBorrow(PyFrameObject *frame)
{
return (PyFrameObject *)_Py_XStealRef(PyFrame_GetBack(frame));
return PYCAPI_COMPAT_CAST(PyFrameObject *,
_Py_XStealRef(PyFrame_GetBack(frame)));
}
#endif


// bpo-39947 added PyThreadState_GetInterpreter() to Python 3.9.0a5
#if PY_VERSION_HEX < 0x030900A5
static inline PyInterpreterState *
PYCAPI_COMPAT_STATIC_INLINE(PyInterpreterState *)
PyThreadState_GetInterpreter(PyThreadState *tstate)
{
assert(tstate != NULL);
assert(tstate != PYCAPI_COMPAT_NULL);
return tstate->interp;
}
#endif


// bpo-40429 added PyThreadState_GetFrame() to Python 3.9.0b1
#if PY_VERSION_HEX < 0x030900B1 && !defined(PYPY_VERSION)
static inline PyFrameObject*
PYCAPI_COMPAT_STATIC_INLINE(PyFrameObject*)
PyThreadState_GetFrame(PyThreadState *tstate)
{
assert(tstate != NULL);
return (PyFrameObject *)Py_XNewRef(tstate->frame);
assert(tstate != PYCAPI_COMPAT_NULL);
return PYCAPI_COMPAT_CAST(PyFrameObject *, Py_XNewRef(tstate->frame));
}
#endif

#if !defined(PYPY_VERSION)
static inline PyFrameObject*
PYCAPI_COMPAT_STATIC_INLINE(PyFrameObject*)
_PyThreadState_GetFrameBorrow(PyThreadState *tstate)
{
return (PyFrameObject *)_Py_XStealRef(PyThreadState_GetFrame(tstate));
return PYCAPI_COMPAT_CAST(PyFrameObject*,
_Py_XStealRef(PyThreadState_GetFrame(tstate)));
}
#endif


// bpo-39947 added PyInterpreterState_Get() to Python 3.9.0a5
#if PY_VERSION_HEX < 0x030900A5
static inline PyInterpreterState *
PYCAPI_COMPAT_STATIC_INLINE(PyInterpreterState*)
PyInterpreterState_Get(void)
{
PyThreadState *tstate;
PyInterpreterState *interp;

tstate = PyThreadState_GET();
if (tstate == NULL) {
if (tstate == PYCAPI_COMPAT_NULL) {
Py_FatalError("GIL released (tstate is NULL)");
}
interp = tstate->interp;
if (interp == NULL) {
if (interp == PYCAPI_COMPAT_NULL) {
Py_FatalError("no current interpreter");
}
return interp;
Expand All @@ -243,17 +260,18 @@ PyInterpreterState_Get(void)

// bpo-39947 added PyInterpreterState_Get() to Python 3.9.0a6
#if 0x030700A1 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x030900A6 && !defined(PYPY_VERSION)
static inline uint64_t
PYCAPI_COMPAT_STATIC_INLINE(uint64_t)
PyThreadState_GetID(PyThreadState *tstate)
{
assert(tstate != NULL);
assert(tstate != PYCAPI_COMPAT_NULL);
return tstate->id;
}
#endif

// bpo-43760 added PyThreadState_EnterTracing() to Python 3.11.0a2
#if PY_VERSION_HEX < 0x030B00A2 && !defined(PYPY_VERSION)
static inline void PyThreadState_EnterTracing(PyThreadState *tstate)
PYCAPI_COMPAT_STATIC_INLINE(void)
PyThreadState_EnterTracing(PyThreadState *tstate)
{
tstate->tracing++;
#if PY_VERSION_HEX >= 0x030A00A1
Expand All @@ -266,10 +284,11 @@ static inline void PyThreadState_EnterTracing(PyThreadState *tstate)

// bpo-43760 added PyThreadState_LeaveTracing() to Python 3.11.0a2
#if PY_VERSION_HEX < 0x030B00A2 && !defined(PYPY_VERSION)
static inline void PyThreadState_LeaveTracing(PyThreadState *tstate)
PYCAPI_COMPAT_STATIC_INLINE(void)
PyThreadState_LeaveTracing(PyThreadState *tstate)
{
int use_tracing = (tstate->c_tracefunc != NULL
|| tstate->c_profilefunc != NULL);
int use_tracing = (tstate->c_tracefunc != PYCAPI_COMPAT_NULL
|| tstate->c_profilefunc != PYCAPI_COMPAT_NULL);
tstate->tracing--;
#if PY_VERSION_HEX >= 0x030A00A1
tstate->cframe->use_tracing = use_tracing;
Expand All @@ -282,7 +301,7 @@ static inline void PyThreadState_LeaveTracing(PyThreadState *tstate)

// bpo-37194 added PyObject_CallNoArgs() to Python 3.9.0a1
#if PY_VERSION_HEX < 0x030900A1
static inline PyObject*
PYCAPI_COMPAT_STATIC_INLINE(PyObject*)
PyObject_CallNoArgs(PyObject *func)
{
return PyObject_CallFunctionObjArgs(func, NULL);
Expand All @@ -293,7 +312,7 @@ PyObject_CallNoArgs(PyObject *func)
// bpo-39245 made PyObject_CallOneArg() public (previously called
// _PyObject_CallOneArg) in Python 3.9.0a4
#if PY_VERSION_HEX < 0x030900A4
static inline PyObject*
PYCAPI_COMPAT_STATIC_INLINE(PyObject*)
PyObject_CallOneArg(PyObject *func, PyObject *arg)
{
return PyObject_CallFunctionObjArgs(func, arg, NULL);
Expand All @@ -303,7 +322,7 @@ PyObject_CallOneArg(PyObject *func, PyObject *arg)

// bpo-1635741 added PyModule_AddObjectRef() to Python 3.10.0a3
#if PY_VERSION_HEX < 0x030A00A3
static inline int
PYCAPI_COMPAT_STATIC_INLINE(int)
PyModule_AddObjectRef(PyObject *module, const char *name, PyObject *value)
{
int res;
Expand All @@ -319,7 +338,7 @@ PyModule_AddObjectRef(PyObject *module, const char *name, PyObject *value)

// bpo-40024 added PyModule_AddType() to Python 3.9.0a5
#if PY_VERSION_HEX < 0x030900A5
static inline int
PYCAPI_COMPAT_STATIC_INLINE(int)
PyModule_AddType(PyObject *module, PyTypeObject *type)
{
const char *name, *dot;
Expand All @@ -330,21 +349,21 @@ PyModule_AddType(PyObject *module, PyTypeObject *type)

// inline _PyType_Name()
name = type->tp_name;
assert(name != NULL);
assert(name != PYCAPI_COMPAT_NULL);
dot = strrchr(name, '.');
if (dot != NULL) {
if (dot != PYCAPI_COMPAT_NULL) {
name = dot + 1;
}

return PyModule_AddObjectRef(module, name, (PyObject *)type);
return PyModule_AddObjectRef(module, name, _PyObject_CAST(type));
}
#endif


// bpo-40241 added PyObject_GC_IsTracked() to Python 3.9.0a6.
// bpo-4688 added _PyObject_GC_IS_TRACKED() to Python 2.7.0a2.
#if PY_VERSION_HEX < 0x030900A6 && !defined(PYPY_VERSION)
static inline int
PYCAPI_COMPAT_STATIC_INLINE(int)
PyObject_GC_IsTracked(PyObject* obj)
{
return (PyObject_IS_GC(obj) && _PyObject_GC_IS_TRACKED(obj));
Expand All @@ -354,17 +373,18 @@ PyObject_GC_IsTracked(PyObject* obj)
// bpo-40241 added PyObject_GC_IsFinalized() to Python 3.9.0a6.
// bpo-18112 added _PyGCHead_FINALIZED() to Python 3.4.0 final.
#if PY_VERSION_HEX < 0x030900A6 && PY_VERSION_HEX >= 0x030400F0 && !defined(PYPY_VERSION)
static inline int
PYCAPI_COMPAT_STATIC_INLINE(int)
PyObject_GC_IsFinalized(PyObject *obj)
{
return (PyObject_IS_GC(obj) && _PyGCHead_FINALIZED((PyGC_Head *)(obj)-1));
PyGC_Head *gc = PYCAPI_COMPAT_CAST(PyGC_Head *, obj) - 1;
return (PyObject_IS_GC(obj) && _PyGCHead_FINALIZED(gc));
}
#endif


// bpo-39573 added Py_IS_TYPE() to Python 3.9.0a4
#if PY_VERSION_HEX < 0x030900A4 && !defined(Py_IS_TYPE)
static inline int
PYCAPI_COMPAT_STATIC_INLINE(int)
_Py_IS_TYPE(const PyObject *ob, const PyTypeObject *type) {
return ob->ob_type == type;
}
Expand All @@ -382,11 +402,6 @@ _Py_IS_TYPE(const PyObject *ob, const PyTypeObject *type) {
#endif


#ifdef PYTHONCAPI_COMPAT_MSC_INLINE
# undef inline
# undef PYTHONCAPI_COMPAT_MSC_INLINE
#endif

#ifdef __cplusplus
}
#endif
Expand Down