pythoncapi_compat.h 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  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. // SPDX-License-Identifier: MIT
  13. #ifndef PYTHONCAPI_COMPAT
  14. #define PYTHONCAPI_COMPAT
  15. #ifdef __cplusplus
  16. extern "C" {
  17. #endif
  18. #include <Python.h>
  19. #include "frameobject.h" // PyFrameObject, PyFrame_GetBack()
  20. // Compatibility with Visual Studio 2013 and older which don't support
  21. // the inline keyword in C (only in C++): use __inline instead.
  22. #if (defined(_MSC_VER) && _MSC_VER < 1900 \
  23. && !defined(__cplusplus) && !defined(inline))
  24. # define inline __inline
  25. # define PYTHONCAPI_COMPAT_MSC_INLINE
  26. // These two macros are undefined at the end of this file
  27. #endif
  28. // Cast argument to PyObject* type.
  29. #ifndef _PyObject_CAST
  30. # define _PyObject_CAST(op) ((PyObject*)(op))
  31. #endif
  32. #ifndef _PyObject_CAST_CONST
  33. # define _PyObject_CAST_CONST(op) ((const PyObject*)(op))
  34. #endif
  35. // bpo-42262 added Py_NewRef() to Python 3.10.0a3
  36. #if PY_VERSION_HEX < 0x030A00A3 && !defined(Py_NewRef)
  37. static inline PyObject* _Py_NewRef(PyObject *obj)
  38. {
  39. Py_INCREF(obj);
  40. return obj;
  41. }
  42. #define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj))
  43. #endif
  44. // bpo-42262 added Py_XNewRef() to Python 3.10.0a3
  45. #if PY_VERSION_HEX < 0x030A00A3 && !defined(Py_XNewRef)
  46. static inline PyObject* _Py_XNewRef(PyObject *obj)
  47. {
  48. Py_XINCREF(obj);
  49. return obj;
  50. }
  51. #define Py_XNewRef(obj) _Py_XNewRef(_PyObject_CAST(obj))
  52. #endif
  53. // bpo-39573 added Py_SET_REFCNT() to Python 3.9.0a4
  54. #if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_REFCNT)
  55. static inline void _Py_SET_REFCNT(PyObject *ob, Py_ssize_t refcnt)
  56. {
  57. ob->ob_refcnt = refcnt;
  58. }
  59. #define Py_SET_REFCNT(ob, refcnt) _Py_SET_REFCNT(_PyObject_CAST(ob), refcnt)
  60. #endif
  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_CAST(ob), type)
  69. #endif
  70. // bpo-39573 added Py_SET_SIZE() to Python 3.9.0a4
  71. #if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_SIZE)
  72. static inline void
  73. _Py_SET_SIZE(PyVarObject *ob, Py_ssize_t size)
  74. {
  75. ob->ob_size = size;
  76. }
  77. #define Py_SET_SIZE(ob, size) _Py_SET_SIZE((PyVarObject*)(ob), size)
  78. #endif
  79. // bpo-40421 added PyFrame_GetCode() to Python 3.9.0b1
  80. #if PY_VERSION_HEX < 0x030900B1
  81. static inline PyCodeObject*
  82. PyFrame_GetCode(PyFrameObject *frame)
  83. {
  84. PyCodeObject *code;
  85. assert(frame != NULL);
  86. code = frame->f_code;
  87. assert(code != NULL);
  88. Py_INCREF(code);
  89. return code;
  90. }
  91. #endif
  92. static inline PyCodeObject*
  93. _PyFrame_GetCodeBorrow(PyFrameObject *frame)
  94. {
  95. PyCodeObject *code = PyFrame_GetCode(frame);
  96. Py_DECREF(code);
  97. return code; // borrowed reference
  98. }
  99. // bpo-40421 added PyFrame_GetCode() to Python 3.9.0b1
  100. #if PY_VERSION_HEX < 0x030900B1
  101. static inline PyFrameObject*
  102. PyFrame_GetBack(PyFrameObject *frame)
  103. {
  104. PyFrameObject *back;
  105. assert(frame != NULL);
  106. back = frame->f_back;
  107. Py_XINCREF(back);
  108. return back;
  109. }
  110. #endif
  111. static inline PyFrameObject*
  112. _PyFrame_GetBackBorrow(PyFrameObject *frame)
  113. {
  114. PyFrameObject *back = PyFrame_GetBack(frame);
  115. Py_XDECREF(back);
  116. return back; // borrowed reference
  117. }
  118. // bpo-39947 added PyThreadState_GetInterpreter() to Python 3.9.0a5
  119. #if PY_VERSION_HEX < 0x030900A5
  120. static inline PyInterpreterState *
  121. PyThreadState_GetInterpreter(PyThreadState *tstate)
  122. {
  123. assert(tstate != NULL);
  124. return tstate->interp;
  125. }
  126. #endif
  127. // bpo-40429 added PyThreadState_GetFrame() to Python 3.9.0b1
  128. #if PY_VERSION_HEX < 0x030900B1
  129. static inline PyFrameObject*
  130. PyThreadState_GetFrame(PyThreadState *tstate)
  131. {
  132. PyFrameObject *frame;
  133. assert(tstate != NULL);
  134. frame = tstate->frame;
  135. Py_XINCREF(frame);
  136. return frame;
  137. }
  138. #endif
  139. static inline PyFrameObject*
  140. _PyThreadState_GetFrameBorrow(PyThreadState *tstate)
  141. {
  142. PyFrameObject *frame = PyThreadState_GetFrame(tstate);
  143. Py_XDECREF(frame);
  144. return frame; // borrowed reference
  145. }
  146. // bpo-39947 added PyInterpreterState_Get() to Python 3.9.0a5
  147. #if PY_VERSION_HEX < 0x030900A5
  148. static inline PyInterpreterState *
  149. PyInterpreterState_Get(void)
  150. {
  151. PyThreadState *tstate;
  152. PyInterpreterState *interp;
  153. tstate = PyThreadState_GET();
  154. if (tstate == NULL) {
  155. Py_FatalError("GIL released (tstate is NULL)");
  156. }
  157. interp = tstate->interp;
  158. if (interp == NULL) {
  159. Py_FatalError("no current interpreter");
  160. }
  161. return interp;
  162. }
  163. #endif
  164. // bpo-39947 added PyInterpreterState_Get() to Python 3.9.0a6
  165. #if 0x030700A1 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x030900A6
  166. static inline uint64_t
  167. PyThreadState_GetID(PyThreadState *tstate)
  168. {
  169. assert(tstate != NULL);
  170. return tstate->id;
  171. }
  172. #endif
  173. // bpo-37194 added PyObject_CallNoArgs() to Python 3.9.0a1
  174. #if PY_VERSION_HEX < 0x030900A1
  175. static inline PyObject*
  176. PyObject_CallNoArgs(PyObject *func)
  177. {
  178. return PyObject_CallFunctionObjArgs(func, NULL);
  179. }
  180. #endif
  181. // bpo-39245 made PyObject_CallOneArg() public (previously called
  182. // _PyObject_CallOneArg) in Python 3.9.0a4
  183. #if PY_VERSION_HEX < 0x030900A4
  184. static inline PyObject*
  185. PyObject_CallOneArg(PyObject *func, PyObject *arg)
  186. {
  187. return PyObject_CallFunctionObjArgs(func, arg, NULL);
  188. }
  189. #endif
  190. // bpo-1635741 added PyModule_AddObjectRef() to Python 3.10.0a3
  191. #if PY_VERSION_HEX < 0x030A00A3
  192. static inline int
  193. PyModule_AddObjectRef(PyObject *module, const char *name, PyObject *value)
  194. {
  195. Py_XINCREF(value);
  196. int res = PyModule_AddObject(module, name, value);
  197. if (res < 0) {
  198. Py_XDECREF(value);
  199. }
  200. return res;
  201. }
  202. #endif
  203. // bpo-40024 added PyModule_AddType() to Python 3.9.0a5
  204. #if PY_VERSION_HEX < 0x030900A5
  205. static inline int
  206. PyModule_AddType(PyObject *module, PyTypeObject *type)
  207. {
  208. const char *name, *dot;
  209. if (PyType_Ready(type) < 0) {
  210. return -1;
  211. }
  212. // inline _PyType_Name()
  213. name = type->tp_name;
  214. assert(name != NULL);
  215. dot = strrchr(name, '.');
  216. if (dot != NULL) {
  217. name = dot + 1;
  218. }
  219. return PyModule_AddObjectRef(module, name, (PyObject *)type);
  220. }
  221. #endif
  222. // bpo-40241 added PyObject_GC_IsTracked() to Python 3.9.0a6.
  223. // bpo-4688 added _PyObject_GC_IS_TRACKED() to Python 2.7.0a2.
  224. #if PY_VERSION_HEX < 0x030900A6
  225. static inline int
  226. PyObject_GC_IsTracked(PyObject* obj)
  227. {
  228. return (PyObject_IS_GC(obj) && _PyObject_GC_IS_TRACKED(obj));
  229. }
  230. #endif
  231. // bpo-40241 added PyObject_GC_IsFinalized() to Python 3.9.0a6.
  232. // bpo-18112 added _PyGCHead_FINALIZED() to Python 3.4.0 final.
  233. #if PY_VERSION_HEX < 0x030900A6 && PY_VERSION_HEX >= 0x030400F0
  234. static inline int
  235. PyObject_GC_IsFinalized(PyObject *obj)
  236. {
  237. return (PyObject_IS_GC(obj) && _PyGCHead_FINALIZED((PyGC_Head *)(obj)-1));
  238. }
  239. #endif
  240. // bpo-39573 added Py_IS_TYPE() to Python 3.9.0a4
  241. #if PY_VERSION_HEX < 0x030900A4 && !defined(Py_IS_TYPE)
  242. static inline int
  243. _Py_IS_TYPE(const PyObject *ob, const PyTypeObject *type) {
  244. return ob->ob_type == type;
  245. }
  246. #define Py_IS_TYPE(ob, type) _Py_IS_TYPE(_PyObject_CAST_CONST(ob), type)
  247. #endif
  248. #ifdef PYTHONCAPI_COMPAT_MSC_INLINE
  249. # undef inline
  250. # undef PYTHONCAPI_COMPAT_MSC_INLINE
  251. #endif
  252. #ifdef __cplusplus
  253. }
  254. #endif
  255. #endif // PYTHONCAPI_COMPAT