Skip to content

Commit

Permalink
Update pythoncapi_compat.h
Browse files Browse the repository at this point in the history
Fix compatibility with Visual Studio 2008 for Python 2.7:
* https://phab.mercurial-scm.org/D9867
* python/pythoncapi-compat#3
  • Loading branch information
vstinner authored and indygreg committed Feb 26, 2021
1 parent 060d41d commit 477776e
Showing 1 changed file with 119 additions and 40 deletions.
159 changes: 119 additions & 40 deletions c-ext/pythoncapi_compat.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,58 +19,87 @@ extern "C" {
#endif

#include <Python.h>
#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;
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -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;

Expand All @@ -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) {
Expand All @@ -188,41 +260,48 @@ 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

// 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

0 comments on commit 477776e

Please sign in to comment.