diff --git a/c-ext/pythoncapi_compat.h b/c-ext/pythoncapi_compat.h index 7f028529..450d7ed6 100644 --- a/c-ext/pythoncapi_compat.h +++ b/c-ext/pythoncapi_compat.h @@ -19,58 +19,87 @@ extern "C" { #endif #include -#include "frameobject.h" // PyFrameObject, PyFrame_GetBack() +#include "frameobject.h" // PyFrameObject, PyFrame_GetBack() + + +// Compatibility with Visual Studio 2013 and older which don't support +// 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 +#endif + // Cast argument to PyObject* type. #ifndef _PyObject_CAST -#define _PyObject_CAST(op) ((PyObject *)(op)) +# define _PyObject_CAST(op) ((PyObject*)(op)) +#endif +#ifndef _PyObject_CAST_CONST +# define _PyObject_CAST_CONST(op) ((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) { +#if PY_VERSION_HEX < 0x030A00A3 && !defined(Py_NewRef) +static inline PyObject* _Py_NewRef(PyObject *obj) +{ Py_INCREF(obj); return obj; } #define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj)) #endif + // 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) { +#if PY_VERSION_HEX < 0x030A00A3 && !defined(Py_XNewRef) +static inline PyObject* _Py_XNewRef(PyObject *obj) +{ Py_XINCREF(obj); return obj; } #define Py_XNewRef(obj) _Py_XNewRef(_PyObject_CAST(obj)) #endif + // 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) { +static inline void _Py_SET_REFCNT(PyObject *ob, Py_ssize_t refcnt) +{ ob->ob_refcnt = refcnt; } -#define Py_SET_REFCNT(ob, refcnt) _Py_SET_REFCNT((PyObject *)(ob), refcnt) +#define Py_SET_REFCNT(ob, refcnt) _Py_SET_REFCNT(_PyObject_CAST(ob), refcnt) #endif + // bpo-39573 added Py_SET_TYPE() to Python 3.9.0a4 #if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_TYPE) -static inline void _Py_SET_TYPE(PyObject *ob, PyTypeObject *type) { +static inline void +_Py_SET_TYPE(PyObject *ob, PyTypeObject *type) +{ ob->ob_type = type; } -#define Py_SET_TYPE(ob, type) _Py_SET_TYPE((PyObject *)(ob), type) +#define Py_SET_TYPE(ob, type) _Py_SET_TYPE(_PyObject_CAST(ob), type) #endif + // bpo-39573 added Py_SET_SIZE() to Python 3.9.0a4 #if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_SIZE) -static inline void _Py_SET_SIZE(PyVarObject *ob, Py_ssize_t size) { +static inline void +_Py_SET_SIZE(PyVarObject *ob, Py_ssize_t size) +{ ob->ob_size = size; } -#define Py_SET_SIZE(ob, size) _Py_SET_SIZE((PyVarObject *)(ob), size) +#define Py_SET_SIZE(ob, size) _Py_SET_SIZE((PyVarObject*)(ob), size) #endif + // bpo-40421 added PyFrame_GetCode() to Python 3.9.0b1 #if PY_VERSION_HEX < 0x030900B1 -static inline PyCodeObject *PyFrame_GetCode(PyFrameObject *frame) { +static inline PyCodeObject* +PyFrame_GetCode(PyFrameObject *frame) +{ PyCodeObject *code; assert(frame != NULL); code = frame->f_code; @@ -80,15 +109,20 @@ static inline PyCodeObject *PyFrame_GetCode(PyFrameObject *frame) { } #endif -static inline PyCodeObject *_PyFrame_GetCodeBorrow(PyFrameObject *frame) { +static inline PyCodeObject* +_PyFrame_GetCodeBorrow(PyFrameObject *frame) +{ PyCodeObject *code = PyFrame_GetCode(frame); Py_DECREF(code); - return code; // borrowed reference + return code; // borrowed reference } + // bpo-40421 added PyFrame_GetCode() to Python 3.9.0b1 #if PY_VERSION_HEX < 0x030900B1 -static inline PyFrameObject *PyFrame_GetBack(PyFrameObject *frame) { +static inline PyFrameObject* +PyFrame_GetBack(PyFrameObject *frame) +{ PyFrameObject *back; assert(frame != NULL); back = frame->f_back; @@ -97,24 +131,31 @@ static inline PyFrameObject *PyFrame_GetBack(PyFrameObject *frame) { } #endif -static inline PyFrameObject *_PyFrame_GetBackBorrow(PyFrameObject *frame) { +static inline PyFrameObject* +_PyFrame_GetBackBorrow(PyFrameObject *frame) +{ PyFrameObject *back = PyFrame_GetBack(frame); Py_XDECREF(back); - return back; // borrowed reference + return back; // borrowed reference } + // bpo-39947 added PyThreadState_GetInterpreter() to Python 3.9.0a5 #if PY_VERSION_HEX < 0x030900A5 static inline PyInterpreterState * -PyThreadState_GetInterpreter(PyThreadState *tstate) { +PyThreadState_GetInterpreter(PyThreadState *tstate) +{ assert(tstate != NULL); return tstate->interp; } #endif + // bpo-40429 added PyThreadState_GetFrame() to Python 3.9.0b1 #if PY_VERSION_HEX < 0x030900B1 -static inline PyFrameObject *PyThreadState_GetFrame(PyThreadState *tstate) { +static inline PyFrameObject* +PyThreadState_GetFrame(PyThreadState *tstate) +{ PyFrameObject *frame; assert(tstate != NULL); frame = tstate->frame; @@ -123,16 +164,20 @@ static inline PyFrameObject *PyThreadState_GetFrame(PyThreadState *tstate) { } #endif -static inline PyFrameObject * -_PyThreadState_GetFrameBorrow(PyThreadState *tstate) { +static inline PyFrameObject* +_PyThreadState_GetFrameBorrow(PyThreadState *tstate) +{ PyFrameObject *frame = PyThreadState_GetFrame(tstate); Py_XDECREF(frame); - return frame; // borrowed reference + return frame; // borrowed reference } + // bpo-39947 added PyInterpreterState_Get() to Python 3.9.0a5 #if PY_VERSION_HEX < 0x030900A5 -static inline PyInterpreterState *PyInterpreterState_Get(void) { +static inline PyInterpreterState * +PyInterpreterState_Get(void) +{ PyThreadState *tstate; PyInterpreterState *interp; @@ -148,32 +193,59 @@ static inline PyInterpreterState *PyInterpreterState_Get(void) { } #endif + // bpo-39947 added PyInterpreterState_Get() to Python 3.9.0a6 #if 0x030700A1 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x030900A6 -static inline uint64_t PyThreadState_GetID(PyThreadState *tstate) { +static inline uint64_t +PyThreadState_GetID(PyThreadState *tstate) +{ assert(tstate != NULL); return tstate->id; } #endif + // bpo-37194 added PyObject_CallNoArgs() to Python 3.9.0a1 #if PY_VERSION_HEX < 0x030900A1 -static inline PyObject *PyObject_CallNoArgs(PyObject *func) { +static inline PyObject* +PyObject_CallNoArgs(PyObject *func) +{ return PyObject_CallFunctionObjArgs(func, NULL); } #endif + // bpo-39245 made PyObject_CallOneArg() public (previously called // _PyObject_CallOneArg) in Python 3.9.0a4 #if PY_VERSION_HEX < 0x030900A4 -static inline PyObject *PyObject_CallOneArg(PyObject *func, PyObject *arg) { +static inline PyObject* +PyObject_CallOneArg(PyObject *func, PyObject *arg) +{ return PyObject_CallFunctionObjArgs(func, arg, NULL); } #endif + +// bpo-1635741 added PyModule_AddObjectRef() to Python 3.10.0a3 +#if PY_VERSION_HEX < 0x030A00A3 +static inline int +PyModule_AddObjectRef(PyObject *module, const char *name, PyObject *value) +{ + Py_XINCREF(value); + int res = PyModule_AddObject(module, name, value); + if (res < 0) { + Py_XDECREF(value); + } + return res; +} +#endif + + // bpo-40024 added PyModule_AddType() to Python 3.9.0a5 #if PY_VERSION_HEX < 0x030900A5 -static inline int PyModule_AddType(PyObject *module, PyTypeObject *type) { +static inline int +PyModule_AddType(PyObject *module, PyTypeObject *type) +{ const char *name, *dot; if (PyType_Ready(type) < 0) { @@ -188,20 +260,17 @@ static inline int PyModule_AddType(PyObject *module, PyTypeObject *type) { name = dot + 1; } - Py_INCREF(type); - if (PyModule_AddObject(module, name, (PyObject *)type) < 0) { - Py_DECREF(type); - return -1; - } - - return 0; + return PyModule_AddObjectRef(module, name, (PyObject *)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 -static inline int PyObject_GC_IsTracked(PyObject *obj) { +static inline int +PyObject_GC_IsTracked(PyObject* obj) +{ return (PyObject_IS_GC(obj) && _PyObject_GC_IS_TRACKED(obj)); } #endif @@ -209,20 +278,30 @@ static inline int 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 -static inline int PyObject_GC_IsFinalized(PyObject *obj) { +static inline int +PyObject_GC_IsFinalized(PyObject *obj) +{ return (PyObject_IS_GC(obj) && _PyGCHead_FINALIZED((PyGC_Head *)(obj)-1)); } #endif + // bpo-39573 added Py_IS_TYPE() to Python 3.9.0a4 #if PY_VERSION_HEX < 0x030900A4 && !defined(Py_IS_TYPE) -static inline int _Py_IS_TYPE(const PyObject *ob, const PyTypeObject *type) { +static inline int +_Py_IS_TYPE(const PyObject *ob, const PyTypeObject *type) { return ob->ob_type == type; } -#define Py_IS_TYPE(ob, type) _Py_IS_TYPE((const PyObject *)(ob), type) +#define Py_IS_TYPE(ob, type) _Py_IS_TYPE(_PyObject_CAST_CONST(ob), type) +#endif + + +#ifdef PYTHONCAPI_COMPAT_MSC_INLINE +# undef inline +# undef PYTHONCAPI_COMPAT_MSC_INLINE #endif #ifdef __cplusplus } #endif -#endif // PYTHONCAPI_COMPAT +#endif // PYTHONCAPI_COMPAT