contrib/python-zstandard/zstd/common/pythoncapi_compat.h
changeset 46374 e92ca942ddca
child 46389 38b9a63d3a13
equal deleted inserted replaced
46373:711ba0f1057e 46374:e92ca942ddca
       
     1 // Header file providing new functions of the Python C API to old Python
       
     2 // versions.
       
     3 //
       
     4 // File distributed under the MIT license.
       
     5 //
       
     6 // Homepage:
       
     7 // https://github.com/pythoncapi/pythoncapi_compat
       
     8 //
       
     9 // Latest version:
       
    10 // https://raw.githubusercontent.com/pythoncapi/pythoncapi_compat/master/pythoncapi_compat.h
       
    11 
       
    12 #ifndef PYTHONCAPI_COMPAT
       
    13 #define PYTHONCAPI_COMPAT
       
    14 
       
    15 #ifdef __cplusplus
       
    16 extern "C" {
       
    17 #endif
       
    18 
       
    19 #include <Python.h>
       
    20 #include "frameobject.h"          // PyFrameObject, PyFrame_GetBack()
       
    21 
       
    22 
       
    23 // Cast argument to PyObject* type.
       
    24 #ifndef _PyObject_CAST
       
    25 #  define _PyObject_CAST(op) ((PyObject*)(op))
       
    26 #endif
       
    27 
       
    28 
       
    29 // bpo-42262 added Py_NewRef() to Python 3.10.0a3
       
    30 #if PY_VERSION_HEX < 0x030a00A3 && !defined(Py_NewRef)
       
    31 static inline PyObject* _Py_NewRef(PyObject *obj)
       
    32 {
       
    33     Py_INCREF(obj);
       
    34     return obj;
       
    35 }
       
    36 #define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
       
    37 #endif
       
    38 
       
    39 
       
    40 // bpo-42262 added Py_XNewRef() to Python 3.10.0a3
       
    41 #if PY_VERSION_HEX < 0x030a00A3 && !defined(Py_XNewRef)
       
    42 static inline PyObject* _Py_XNewRef(PyObject *obj)
       
    43 {
       
    44     Py_XINCREF(obj);
       
    45     return obj;
       
    46 }
       
    47 #define Py_XNewRef(obj) _Py_XNewRef(_PyObject_CAST(obj))
       
    48 #endif
       
    49 
       
    50 
       
    51 // bpo-39573 added Py_SET_REFCNT() to Python 3.9.0a4
       
    52 #if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_REFCNT)
       
    53 static inline void _Py_SET_REFCNT(PyObject *ob, Py_ssize_t refcnt)
       
    54 {
       
    55     ob->ob_refcnt = refcnt;
       
    56 }
       
    57 #define Py_SET_REFCNT(ob, refcnt) _Py_SET_REFCNT((PyObject*)(ob), refcnt)
       
    58 #endif
       
    59 
       
    60 
       
    61 // bpo-39573 added Py_SET_TYPE() to Python 3.9.0a4
       
    62 #if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_TYPE)
       
    63 static inline void
       
    64 _Py_SET_TYPE(PyObject *ob, PyTypeObject *type)
       
    65 {
       
    66     ob->ob_type = type;
       
    67 }
       
    68 #define Py_SET_TYPE(ob, type) _Py_SET_TYPE((PyObject*)(ob), type)
       
    69 #endif
       
    70 
       
    71 
       
    72 // bpo-39573 added Py_SET_SIZE() to Python 3.9.0a4
       
    73 #if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_SIZE)
       
    74 static inline void
       
    75 _Py_SET_SIZE(PyVarObject *ob, Py_ssize_t size)
       
    76 {
       
    77     ob->ob_size = size;
       
    78 }
       
    79 #define Py_SET_SIZE(ob, size) _Py_SET_SIZE((PyVarObject*)(ob), size)
       
    80 #endif
       
    81 
       
    82 
       
    83 // bpo-40421 added PyFrame_GetCode() to Python 3.9.0b1
       
    84 #if PY_VERSION_HEX < 0x030900B1
       
    85 static inline PyCodeObject*
       
    86 PyFrame_GetCode(PyFrameObject *frame)
       
    87 {
       
    88     PyCodeObject *code;
       
    89     assert(frame != NULL);
       
    90     code = frame->f_code;
       
    91     assert(code != NULL);
       
    92     Py_INCREF(code);
       
    93     return code;
       
    94 }
       
    95 #endif
       
    96 
       
    97 static inline PyCodeObject*
       
    98 _PyFrame_GetCodeBorrow(PyFrameObject *frame)
       
    99 {
       
   100     PyCodeObject *code = PyFrame_GetCode(frame);
       
   101     Py_DECREF(code);
       
   102     return code;  // borrowed reference
       
   103 }
       
   104 
       
   105 
       
   106 // bpo-40421 added PyFrame_GetCode() to Python 3.9.0b1
       
   107 #if PY_VERSION_HEX < 0x030900B1
       
   108 static inline PyFrameObject*
       
   109 PyFrame_GetBack(PyFrameObject *frame)
       
   110 {
       
   111     PyFrameObject *back;
       
   112     assert(frame != NULL);
       
   113     back = frame->f_back;
       
   114     Py_XINCREF(back);
       
   115     return back;
       
   116 }
       
   117 #endif
       
   118 
       
   119 static inline PyFrameObject*
       
   120 _PyFrame_GetBackBorrow(PyFrameObject *frame)
       
   121 {
       
   122     PyFrameObject *back = PyFrame_GetBack(frame);
       
   123     Py_XDECREF(back);
       
   124     return back;  // borrowed reference
       
   125 }
       
   126 
       
   127 
       
   128 // bpo-39947 added PyThreadState_GetInterpreter() to Python 3.9.0a5
       
   129 #if PY_VERSION_HEX < 0x030900A5
       
   130 static inline PyInterpreterState *
       
   131 PyThreadState_GetInterpreter(PyThreadState *tstate)
       
   132 {
       
   133     assert(tstate != NULL);
       
   134     return tstate->interp;
       
   135 }
       
   136 #endif
       
   137 
       
   138 
       
   139 // bpo-40429 added PyThreadState_GetFrame() to Python 3.9.0b1
       
   140 #if PY_VERSION_HEX < 0x030900B1
       
   141 static inline PyFrameObject*
       
   142 PyThreadState_GetFrame(PyThreadState *tstate)
       
   143 {
       
   144     PyFrameObject *frame;
       
   145     assert(tstate != NULL);
       
   146     frame = tstate->frame;
       
   147     Py_XINCREF(frame);
       
   148     return frame;
       
   149 }
       
   150 #endif
       
   151 
       
   152 static inline PyFrameObject*
       
   153 _PyThreadState_GetFrameBorrow(PyThreadState *tstate)
       
   154 {
       
   155     PyFrameObject *frame = PyThreadState_GetFrame(tstate);
       
   156     Py_XDECREF(frame);
       
   157     return frame;  // borrowed reference
       
   158 }
       
   159 
       
   160 
       
   161 // bpo-39947 added PyInterpreterState_Get() to Python 3.9.0a5
       
   162 #if PY_VERSION_HEX < 0x030900A5
       
   163 static inline PyInterpreterState *
       
   164 PyInterpreterState_Get(void)
       
   165 {
       
   166     PyThreadState *tstate;
       
   167     PyInterpreterState *interp;
       
   168 
       
   169     tstate = PyThreadState_GET();
       
   170     if (tstate == NULL) {
       
   171         Py_FatalError("GIL released (tstate is NULL)");
       
   172     }
       
   173     interp = tstate->interp;
       
   174     if (interp == NULL) {
       
   175         Py_FatalError("no current interpreter");
       
   176     }
       
   177     return interp;
       
   178 }
       
   179 #endif
       
   180 
       
   181 
       
   182 // bpo-39947 added PyInterpreterState_Get() to Python 3.9.0a6
       
   183 #if 0x030700A1 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x030900A6
       
   184 static inline uint64_t
       
   185 PyThreadState_GetID(PyThreadState *tstate)
       
   186 {
       
   187     assert(tstate != NULL);
       
   188     return tstate->id;
       
   189 }
       
   190 #endif
       
   191 
       
   192 
       
   193 // bpo-37194 added PyObject_CallNoArgs() to Python 3.9.0a1
       
   194 #if PY_VERSION_HEX < 0x030900A1
       
   195 static inline PyObject*
       
   196 PyObject_CallNoArgs(PyObject *func)
       
   197 {
       
   198     return PyObject_CallFunctionObjArgs(func, NULL);
       
   199 }
       
   200 #endif
       
   201 
       
   202 
       
   203 // bpo-39245 made PyObject_CallOneArg() public (previously called
       
   204 // _PyObject_CallOneArg) in Python 3.9.0a4
       
   205 #if PY_VERSION_HEX < 0x030900A4
       
   206 static inline PyObject*
       
   207 PyObject_CallOneArg(PyObject *func, PyObject *arg)
       
   208 {
       
   209     return PyObject_CallFunctionObjArgs(func, arg, NULL);
       
   210 }
       
   211 #endif
       
   212 
       
   213 
       
   214 // bpo-40024 added PyModule_AddType() to Python 3.9.0a5
       
   215 #if PY_VERSION_HEX < 0x030900A5
       
   216 static inline int
       
   217 PyModule_AddType(PyObject *module, PyTypeObject *type)
       
   218 {
       
   219     const char *name, *dot;
       
   220 
       
   221     if (PyType_Ready(type) < 0) {
       
   222         return -1;
       
   223     }
       
   224 
       
   225     // inline _PyType_Name()
       
   226     name = type->tp_name;
       
   227     assert(name != NULL);
       
   228     dot = strrchr(name, '.');
       
   229     if (dot != NULL) {
       
   230         name = dot + 1;
       
   231     }
       
   232 
       
   233     Py_INCREF(type);
       
   234     if (PyModule_AddObject(module, name, (PyObject *)type) < 0) {
       
   235         Py_DECREF(type);
       
   236         return -1;
       
   237     }
       
   238 
       
   239     return 0;
       
   240 }
       
   241 #endif
       
   242 
       
   243 
       
   244 // bpo-40241 added PyObject_GC_IsTracked() to Python 3.9.0a6.
       
   245 // bpo-4688 added _PyObject_GC_IS_TRACKED() to Python 2.7.0a2.
       
   246 #if PY_VERSION_HEX < 0x030900A6
       
   247 static inline int
       
   248 PyObject_GC_IsTracked(PyObject* obj)
       
   249 {
       
   250     return (PyObject_IS_GC(obj) && _PyObject_GC_IS_TRACKED(obj));
       
   251 }
       
   252 #endif
       
   253 
       
   254 // bpo-40241 added PyObject_GC_IsFinalized() to Python 3.9.0a6.
       
   255 // bpo-18112 added _PyGCHead_FINALIZED() to Python 3.4.0 final.
       
   256 #if PY_VERSION_HEX < 0x030900A6 && PY_VERSION_HEX >= 0x030400F0
       
   257 static inline int
       
   258 PyObject_GC_IsFinalized(PyObject *obj)
       
   259 {
       
   260     return (PyObject_IS_GC(obj) && _PyGCHead_FINALIZED((PyGC_Head *)(obj)-1));
       
   261 }
       
   262 #endif
       
   263 
       
   264 
       
   265 // bpo-39573 added Py_IS_TYPE() to Python 3.9.0a4
       
   266 #if PY_VERSION_HEX < 0x030900A4 && !defined(Py_IS_TYPE)
       
   267 static inline int
       
   268 _Py_IS_TYPE(const PyObject *ob, const PyTypeObject *type) {
       
   269     return ob->ob_type == type;
       
   270 }
       
   271 #define Py_IS_TYPE(ob, type) _Py_IS_TYPE((const PyObject*)(ob), type)
       
   272 #endif
       
   273 
       
   274 
       
   275 #ifdef __cplusplus
       
   276 }
       
   277 #endif
       
   278 #endif  // PYTHONCAPI_COMPAT