1 | // Header file providing new C API functions to old Python versions. |
2 | // |
3 | // File distributed under the Zero Clause BSD (0BSD) license. |
4 | // Copyright Contributors to the pythoncapi_compat project. |
5 | // |
6 | // Homepage: |
7 | // https://github.com/python/pythoncapi_compat |
8 | // |
9 | // Latest version: |
10 | // https://raw.githubusercontent.com/python/pythoncapi_compat/master/pythoncapi_compat.h |
11 | // |
12 | // SPDX-License-Identifier: 0BSD |
13 | |
14 | #ifndef PYTHONCAPI_COMPAT |
15 | #define PYTHONCAPI_COMPAT |
16 | |
17 | #ifdef __cplusplus |
18 | extern "C" { |
19 | #endif |
20 | |
21 | #include <Python.h> |
22 | #include "frameobject.h" // PyFrameObject, PyFrame_GetBack() |
23 | |
24 | |
25 | // Compatibility with Visual Studio 2013 and older which don't support |
26 | // the inline keyword in C (only in C++): use __inline instead. |
27 | #if (defined(_MSC_VER) && _MSC_VER < 1900 \ |
28 | && !defined(__cplusplus) && !defined(inline)) |
29 | # define PYCAPI_COMPAT_STATIC_INLINE(TYPE) static __inline TYPE |
30 | #else |
31 | # define PYCAPI_COMPAT_STATIC_INLINE(TYPE) static inline TYPE |
32 | #endif |
33 | |
34 | |
35 | #ifndef _Py_CAST |
36 | # define _Py_CAST(type, expr) ((type)(expr)) |
37 | #endif |
38 | |
39 | // On C++11 and newer, _Py_NULL is defined as nullptr on C++11, |
40 | // otherwise it is defined as NULL. |
41 | #ifndef _Py_NULL |
42 | # if defined(__cplusplus) && __cplusplus >= 201103 |
43 | # define _Py_NULL nullptr |
44 | # else |
45 | # define _Py_NULL NULL |
46 | # endif |
47 | #endif |
48 | |
49 | // Cast argument to PyObject* type. |
50 | #ifndef _PyObject_CAST |
51 | # define _PyObject_CAST(op) _Py_CAST(PyObject*, op) |
52 | #endif |
53 | |
54 | |
55 | // bpo-42262 added Py_NewRef() to Python 3.10.0a3 |
56 | #if PY_VERSION_HEX < 0x030A00A3 && !defined(Py_NewRef) |
57 | PYCAPI_COMPAT_STATIC_INLINE(PyObject*) |
58 | _Py_NewRef(PyObject *obj) |
59 | { |
60 | Py_INCREF(obj); |
61 | return obj; |
62 | } |
63 | #define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj)) |
64 | #endif |
65 | |
66 | |
67 | // bpo-42262 added Py_XNewRef() to Python 3.10.0a3 |
68 | #if PY_VERSION_HEX < 0x030A00A3 && !defined(Py_XNewRef) |
69 | PYCAPI_COMPAT_STATIC_INLINE(PyObject*) |
70 | _Py_XNewRef(PyObject *obj) |
71 | { |
72 | Py_XINCREF(obj); |
73 | return obj; |
74 | } |
75 | #define Py_XNewRef(obj) _Py_XNewRef(_PyObject_CAST(obj)) |
76 | #endif |
77 | |
78 | |
79 | // bpo-39573 added Py_SET_REFCNT() to Python 3.9.0a4 |
80 | #if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_REFCNT) |
81 | PYCAPI_COMPAT_STATIC_INLINE(void) |
82 | _Py_SET_REFCNT(PyObject *ob, Py_ssize_t refcnt) |
83 | { |
84 | ob->ob_refcnt = refcnt; |
85 | } |
86 | #define Py_SET_REFCNT(ob, refcnt) _Py_SET_REFCNT(_PyObject_CAST(ob), refcnt) |
87 | #endif |
88 | |
89 | |
90 | // Py_SETREF() and Py_XSETREF() were added to Python 3.5.2. |
91 | // It is excluded from the limited C API. |
92 | #if (PY_VERSION_HEX < 0x03050200 && !defined(Py_SETREF)) && !defined(Py_LIMITED_API) |
93 | #define Py_SETREF(dst, src) \ |
94 | do { \ |
95 | PyObject **_tmp_dst_ptr = _Py_CAST(PyObject**, &(dst)); \ |
96 | PyObject *_tmp_dst = (*_tmp_dst_ptr); \ |
97 | *_tmp_dst_ptr = _PyObject_CAST(src); \ |
98 | Py_DECREF(_tmp_dst); \ |
99 | } while (0) |
100 | |
101 | #define Py_XSETREF(dst, src) \ |
102 | do { \ |
103 | PyObject **_tmp_dst_ptr = _Py_CAST(PyObject**, &(dst)); \ |
104 | PyObject *_tmp_dst = (*_tmp_dst_ptr); \ |
105 | *_tmp_dst_ptr = _PyObject_CAST(src); \ |
106 | Py_XDECREF(_tmp_dst); \ |
107 | } while (0) |
108 | #endif |
109 | |
110 | |
111 | // bpo-43753 added Py_Is(), Py_IsNone(), Py_IsTrue() and Py_IsFalse() |
112 | // to Python 3.10.0b1. |
113 | #if PY_VERSION_HEX < 0x030A00B1 && !defined(Py_Is) |
114 | # define Py_Is(x, y) ((x) == (y)) |
115 | #endif |
116 | #if PY_VERSION_HEX < 0x030A00B1 && !defined(Py_IsNone) |
117 | # define Py_IsNone(x) Py_Is(x, Py_None) |
118 | #endif |
119 | #if PY_VERSION_HEX < 0x030A00B1 && !defined(Py_IsTrue) |
120 | # define Py_IsTrue(x) Py_Is(x, Py_True) |
121 | #endif |
122 | #if PY_VERSION_HEX < 0x030A00B1 && !defined(Py_IsFalse) |
123 | # define Py_IsFalse(x) Py_Is(x, Py_False) |
124 | #endif |
125 | |
126 | |
127 | // bpo-39573 added Py_SET_TYPE() to Python 3.9.0a4 |
128 | #if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_TYPE) |
129 | PYCAPI_COMPAT_STATIC_INLINE(void) |
130 | _Py_SET_TYPE(PyObject *ob, PyTypeObject *type) |
131 | { |
132 | ob->ob_type = type; |
133 | } |
134 | #define Py_SET_TYPE(ob, type) _Py_SET_TYPE(_PyObject_CAST(ob), type) |
135 | #endif |
136 | |
137 | |
138 | // bpo-39573 added Py_SET_SIZE() to Python 3.9.0a4 |
139 | #if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_SIZE) |
140 | PYCAPI_COMPAT_STATIC_INLINE(void) |
141 | _Py_SET_SIZE(PyVarObject *ob, Py_ssize_t size) |
142 | { |
143 | ob->ob_size = size; |
144 | } |
145 | #define Py_SET_SIZE(ob, size) _Py_SET_SIZE((PyVarObject*)(ob), size) |
146 | #endif |
147 | |
148 | |
149 | // bpo-40421 added PyFrame_GetCode() to Python 3.9.0b1 |
150 | #if PY_VERSION_HEX < 0x030900B1 || defined(PYPY_VERSION) |
151 | PYCAPI_COMPAT_STATIC_INLINE(PyCodeObject*) |
152 | PyFrame_GetCode(PyFrameObject *frame) |
153 | { |
154 | assert(frame != _Py_NULL); |
155 | assert(frame->f_code != _Py_NULL); |
156 | return _Py_CAST(PyCodeObject*, Py_NewRef(frame->f_code)); |
157 | } |
158 | #endif |
159 | |
160 | PYCAPI_COMPAT_STATIC_INLINE(PyCodeObject*) |
161 | _PyFrame_GetCodeBorrow(PyFrameObject *frame) |
162 | { |
163 | PyCodeObject *code = PyFrame_GetCode(frame); |
164 | Py_DECREF(code); |
165 | return code; |
166 | } |
167 | |
168 | |
169 | // bpo-40421 added PyFrame_GetBack() to Python 3.9.0b1 |
170 | #if PY_VERSION_HEX < 0x030900B1 && !defined(PYPY_VERSION) |
171 | PYCAPI_COMPAT_STATIC_INLINE(PyFrameObject*) |
172 | PyFrame_GetBack(PyFrameObject *frame) |
173 | { |
174 | assert(frame != _Py_NULL); |
175 | return _Py_CAST(PyFrameObject*, Py_XNewRef(frame->f_back)); |
176 | } |
177 | #endif |
178 | |
179 | #if !defined(PYPY_VERSION) |
180 | PYCAPI_COMPAT_STATIC_INLINE(PyFrameObject*) |
181 | _PyFrame_GetBackBorrow(PyFrameObject *frame) |
182 | { |
183 | PyFrameObject *back = PyFrame_GetBack(frame); |
184 | Py_XDECREF(back); |
185 | return back; |
186 | } |
187 | #endif |
188 | |
189 | |
190 | // bpo-40421 added PyFrame_GetLocals() to Python 3.11.0a7 |
191 | #if PY_VERSION_HEX < 0x030B00A7 && !defined(PYPY_VERSION) |
192 | PYCAPI_COMPAT_STATIC_INLINE(PyObject*) |
193 | PyFrame_GetLocals(PyFrameObject *frame) |
194 | { |
195 | #if PY_VERSION_HEX >= 0x030400B1 |
196 | if (PyFrame_FastToLocalsWithError(frame) < 0) { |
197 | return NULL; |
198 | } |
199 | #else |
200 | PyFrame_FastToLocals(frame); |
201 | #endif |
202 | return Py_NewRef(frame->f_locals); |
203 | } |
204 | #endif |
205 | |
206 | |
207 | // bpo-40421 added PyFrame_GetGlobals() to Python 3.11.0a7 |
208 | #if PY_VERSION_HEX < 0x030B00A7 && !defined(PYPY_VERSION) |
209 | PYCAPI_COMPAT_STATIC_INLINE(PyObject*) |
210 | PyFrame_GetGlobals(PyFrameObject *frame) |
211 | { |
212 | return Py_NewRef(frame->f_globals); |
213 | } |
214 | #endif |
215 | |
216 | |
217 | // bpo-40421 added PyFrame_GetBuiltins() to Python 3.11.0a7 |
218 | #if PY_VERSION_HEX < 0x030B00A7 && !defined(PYPY_VERSION) |
219 | PYCAPI_COMPAT_STATIC_INLINE(PyObject*) |
220 | PyFrame_GetBuiltins(PyFrameObject *frame) |
221 | { |
222 | return Py_NewRef(frame->f_builtins); |
223 | } |
224 | #endif |
225 | |
226 | |
227 | // bpo-40421 added PyFrame_GetLasti() to Python 3.11.0b1 |
228 | #if PY_VERSION_HEX < 0x030B00B1 && !defined(PYPY_VERSION) |
229 | PYCAPI_COMPAT_STATIC_INLINE(int) |
230 | PyFrame_GetLasti(PyFrameObject *frame) |
231 | { |
232 | #if PY_VERSION_HEX >= 0x030A00A7 |
233 | // bpo-27129: Since Python 3.10.0a7, f_lasti is an instruction offset, |
234 | // not a bytes offset anymore. Python uses 16-bit "wordcode" (2 bytes) |
235 | // instructions. |
236 | if (frame->f_lasti < 0) { |
237 | return -1; |
238 | } |
239 | return frame->f_lasti * 2; |
240 | #else |
241 | return frame->f_lasti; |
242 | #endif |
243 | } |
244 | #endif |
245 | |
246 | |
247 | // gh-91248 added PyFrame_GetVar() to Python 3.12.0a2 |
248 | #if PY_VERSION_HEX < 0x030C00A2 && !defined(PYPY_VERSION) |
249 | PYCAPI_COMPAT_STATIC_INLINE(PyObject*) |
250 | PyFrame_GetVar(PyFrameObject *frame, PyObject *name) |
251 | { |
252 | PyObject *locals, *value; |
253 | |
254 | locals = PyFrame_GetLocals(frame); |
255 | if (locals == NULL) { |
256 | return NULL; |
257 | } |
258 | #if PY_VERSION_HEX >= 0x03000000 |
259 | value = PyDict_GetItemWithError(locals, name); |
260 | #else |
261 | value = PyDict_GetItem(locals, name); |
262 | #endif |
263 | Py_DECREF(locals); |
264 | |
265 | if (value == NULL) { |
266 | if (PyErr_Occurred()) { |
267 | return NULL; |
268 | } |
269 | #if PY_VERSION_HEX >= 0x03000000 |
270 | PyErr_Format(PyExc_NameError, "variable %R does not exist" , name); |
271 | #else |
272 | PyErr_SetString(PyExc_NameError, "variable does not exist" ); |
273 | #endif |
274 | return NULL; |
275 | } |
276 | return Py_NewRef(value); |
277 | } |
278 | #endif |
279 | |
280 | |
281 | // gh-91248 added PyFrame_GetVarString() to Python 3.12.0a2 |
282 | #if PY_VERSION_HEX < 0x030C00A2 && !defined(PYPY_VERSION) |
283 | PYCAPI_COMPAT_STATIC_INLINE(PyObject*) |
284 | PyFrame_GetVarString(PyFrameObject *frame, const char *name) |
285 | { |
286 | PyObject *name_obj, *value; |
287 | name_obj = PyUnicode_FromString(name); |
288 | if (name_obj == NULL) { |
289 | return NULL; |
290 | } |
291 | value = PyFrame_GetVar(frame, name_obj); |
292 | Py_DECREF(name_obj); |
293 | return value; |
294 | } |
295 | #endif |
296 | |
297 | |
298 | // bpo-39947 added PyThreadState_GetInterpreter() to Python 3.9.0a5 |
299 | #if PY_VERSION_HEX < 0x030900A5 || defined(PYPY_VERSION) |
300 | PYCAPI_COMPAT_STATIC_INLINE(PyInterpreterState *) |
301 | PyThreadState_GetInterpreter(PyThreadState *tstate) |
302 | { |
303 | assert(tstate != _Py_NULL); |
304 | return tstate->interp; |
305 | } |
306 | #endif |
307 | |
308 | |
309 | // bpo-40429 added PyThreadState_GetFrame() to Python 3.9.0b1 |
310 | #if PY_VERSION_HEX < 0x030900B1 && !defined(PYPY_VERSION) |
311 | PYCAPI_COMPAT_STATIC_INLINE(PyFrameObject*) |
312 | PyThreadState_GetFrame(PyThreadState *tstate) |
313 | { |
314 | assert(tstate != _Py_NULL); |
315 | return _Py_CAST(PyFrameObject *, Py_XNewRef(tstate->frame)); |
316 | } |
317 | #endif |
318 | |
319 | #if !defined(PYPY_VERSION) |
320 | PYCAPI_COMPAT_STATIC_INLINE(PyFrameObject*) |
321 | _PyThreadState_GetFrameBorrow(PyThreadState *tstate) |
322 | { |
323 | PyFrameObject *frame = PyThreadState_GetFrame(tstate); |
324 | Py_XDECREF(frame); |
325 | return frame; |
326 | } |
327 | #endif |
328 | |
329 | |
330 | // bpo-39947 added PyInterpreterState_Get() to Python 3.9.0a5 |
331 | #if PY_VERSION_HEX < 0x030900A5 || defined(PYPY_VERSION) |
332 | PYCAPI_COMPAT_STATIC_INLINE(PyInterpreterState*) |
333 | PyInterpreterState_Get(void) |
334 | { |
335 | PyThreadState *tstate; |
336 | PyInterpreterState *interp; |
337 | |
338 | tstate = PyThreadState_GET(); |
339 | if (tstate == _Py_NULL) { |
340 | Py_FatalError("GIL released (tstate is NULL)" ); |
341 | } |
342 | interp = tstate->interp; |
343 | if (interp == _Py_NULL) { |
344 | Py_FatalError("no current interpreter" ); |
345 | } |
346 | return interp; |
347 | } |
348 | #endif |
349 | |
350 | |
351 | // bpo-39947 added PyInterpreterState_Get() to Python 3.9.0a6 |
352 | #if 0x030700A1 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x030900A6 && !defined(PYPY_VERSION) |
353 | PYCAPI_COMPAT_STATIC_INLINE(uint64_t) |
354 | PyThreadState_GetID(PyThreadState *tstate) |
355 | { |
356 | assert(tstate != _Py_NULL); |
357 | return tstate->id; |
358 | } |
359 | #endif |
360 | |
361 | // bpo-43760 added PyThreadState_EnterTracing() to Python 3.11.0a2 |
362 | #if PY_VERSION_HEX < 0x030B00A2 && !defined(PYPY_VERSION) |
363 | PYCAPI_COMPAT_STATIC_INLINE(void) |
364 | PyThreadState_EnterTracing(PyThreadState *tstate) |
365 | { |
366 | tstate->tracing++; |
367 | #if PY_VERSION_HEX >= 0x030A00A1 |
368 | tstate->cframe->use_tracing = 0; |
369 | #else |
370 | tstate->use_tracing = 0; |
371 | #endif |
372 | } |
373 | #endif |
374 | |
375 | // bpo-43760 added PyThreadState_LeaveTracing() to Python 3.11.0a2 |
376 | #if PY_VERSION_HEX < 0x030B00A2 && !defined(PYPY_VERSION) |
377 | PYCAPI_COMPAT_STATIC_INLINE(void) |
378 | PyThreadState_LeaveTracing(PyThreadState *tstate) |
379 | { |
380 | int use_tracing = (tstate->c_tracefunc != _Py_NULL |
381 | || tstate->c_profilefunc != _Py_NULL); |
382 | tstate->tracing--; |
383 | #if PY_VERSION_HEX >= 0x030A00A1 |
384 | tstate->cframe->use_tracing = use_tracing; |
385 | #else |
386 | tstate->use_tracing = use_tracing; |
387 | #endif |
388 | } |
389 | #endif |
390 | |
391 | |
392 | // bpo-37194 added PyObject_CallNoArgs() to Python 3.9.0a1 |
393 | #if PY_VERSION_HEX < 0x030900A1 || defined(PYPY_VERSION) |
394 | PYCAPI_COMPAT_STATIC_INLINE(PyObject*) |
395 | PyObject_CallNoArgs(PyObject *func) |
396 | { |
397 | return PyObject_CallFunctionObjArgs(func, NULL); |
398 | } |
399 | #endif |
400 | |
401 | |
402 | // bpo-39245 made PyObject_CallOneArg() public (previously called |
403 | // _PyObject_CallOneArg) in Python 3.9.0a4 |
404 | #if PY_VERSION_HEX < 0x030900A4 || defined(PYPY_VERSION) |
405 | PYCAPI_COMPAT_STATIC_INLINE(PyObject*) |
406 | PyObject_CallOneArg(PyObject *func, PyObject *arg) |
407 | { |
408 | return PyObject_CallFunctionObjArgs(func, arg, NULL); |
409 | } |
410 | #endif |
411 | |
412 | |
413 | // bpo-1635741 added PyModule_AddObjectRef() to Python 3.10.0a3 |
414 | #if PY_VERSION_HEX < 0x030A00A3 |
415 | PYCAPI_COMPAT_STATIC_INLINE(int) |
416 | PyModule_AddObjectRef(PyObject *module, const char *name, PyObject *value) |
417 | { |
418 | int res; |
419 | Py_XINCREF(value); |
420 | res = PyModule_AddObject(module, name, value); |
421 | if (res < 0) { |
422 | Py_XDECREF(value); |
423 | } |
424 | return res; |
425 | } |
426 | #endif |
427 | |
428 | |
429 | // bpo-40024 added PyModule_AddType() to Python 3.9.0a5 |
430 | #if PY_VERSION_HEX < 0x030900A5 |
431 | PYCAPI_COMPAT_STATIC_INLINE(int) |
432 | PyModule_AddType(PyObject *module, PyTypeObject *type) |
433 | { |
434 | const char *name, *dot; |
435 | |
436 | if (PyType_Ready(type) < 0) { |
437 | return -1; |
438 | } |
439 | |
440 | // inline _PyType_Name() |
441 | name = type->tp_name; |
442 | assert(name != _Py_NULL); |
443 | dot = strrchr(name, '.'); |
444 | if (dot != _Py_NULL) { |
445 | name = dot + 1; |
446 | } |
447 | |
448 | return PyModule_AddObjectRef(module, name, _PyObject_CAST(type)); |
449 | } |
450 | #endif |
451 | |
452 | |
453 | // bpo-40241 added PyObject_GC_IsTracked() to Python 3.9.0a6. |
454 | // bpo-4688 added _PyObject_GC_IS_TRACKED() to Python 2.7.0a2. |
455 | #if PY_VERSION_HEX < 0x030900A6 && !defined(PYPY_VERSION) |
456 | PYCAPI_COMPAT_STATIC_INLINE(int) |
457 | PyObject_GC_IsTracked(PyObject* obj) |
458 | { |
459 | return (PyObject_IS_GC(obj) && _PyObject_GC_IS_TRACKED(obj)); |
460 | } |
461 | #endif |
462 | |
463 | // bpo-40241 added PyObject_GC_IsFinalized() to Python 3.9.0a6. |
464 | // bpo-18112 added _PyGCHead_FINALIZED() to Python 3.4.0 final. |
465 | #if PY_VERSION_HEX < 0x030900A6 && PY_VERSION_HEX >= 0x030400F0 && !defined(PYPY_VERSION) |
466 | PYCAPI_COMPAT_STATIC_INLINE(int) |
467 | PyObject_GC_IsFinalized(PyObject *obj) |
468 | { |
469 | PyGC_Head *gc = _Py_CAST(PyGC_Head*, obj) - 1; |
470 | return (PyObject_IS_GC(obj) && _PyGCHead_FINALIZED(gc)); |
471 | } |
472 | #endif |
473 | |
474 | |
475 | // bpo-39573 added Py_IS_TYPE() to Python 3.9.0a4 |
476 | #if PY_VERSION_HEX < 0x030900A4 && !defined(Py_IS_TYPE) |
477 | PYCAPI_COMPAT_STATIC_INLINE(int) |
478 | _Py_IS_TYPE(PyObject *ob, PyTypeObject *type) { |
479 | return Py_TYPE(ob) == type; |
480 | } |
481 | #define Py_IS_TYPE(ob, type) _Py_IS_TYPE(_PyObject_CAST(ob), type) |
482 | #endif |
483 | |
484 | |
485 | // bpo-46906 added PyFloat_Pack2() and PyFloat_Unpack2() to Python 3.11a7. |
486 | // bpo-11734 added _PyFloat_Pack2() and _PyFloat_Unpack2() to Python 3.6.0b1. |
487 | // Python 3.11a2 moved _PyFloat_Pack2() and _PyFloat_Unpack2() to the internal |
488 | // C API: Python 3.11a2-3.11a6 versions are not supported. |
489 | #if 0x030600B1 <= PY_VERSION_HEX && PY_VERSION_HEX <= 0x030B00A1 && !defined(PYPY_VERSION) |
490 | PYCAPI_COMPAT_STATIC_INLINE(int) |
491 | PyFloat_Pack2(double x, char *p, int le) |
492 | { return _PyFloat_Pack2(x, (unsigned char*)p, le); } |
493 | |
494 | PYCAPI_COMPAT_STATIC_INLINE(double) |
495 | PyFloat_Unpack2(const char *p, int le) |
496 | { return _PyFloat_Unpack2((const unsigned char *)p, le); } |
497 | #endif |
498 | |
499 | |
500 | // bpo-46906 added PyFloat_Pack4(), PyFloat_Pack8(), PyFloat_Unpack4() and |
501 | // PyFloat_Unpack8() to Python 3.11a7. |
502 | // Python 3.11a2 moved _PyFloat_Pack4(), _PyFloat_Pack8(), _PyFloat_Unpack4() |
503 | // and _PyFloat_Unpack8() to the internal C API: Python 3.11a2-3.11a6 versions |
504 | // are not supported. |
505 | #if PY_VERSION_HEX <= 0x030B00A1 && !defined(PYPY_VERSION) |
506 | PYCAPI_COMPAT_STATIC_INLINE(int) |
507 | PyFloat_Pack4(double x, char *p, int le) |
508 | { return _PyFloat_Pack4(x, (unsigned char*)p, le); } |
509 | |
510 | PYCAPI_COMPAT_STATIC_INLINE(int) |
511 | PyFloat_Pack8(double x, char *p, int le) |
512 | { return _PyFloat_Pack8(x, (unsigned char*)p, le); } |
513 | |
514 | PYCAPI_COMPAT_STATIC_INLINE(double) |
515 | PyFloat_Unpack4(const char *p, int le) |
516 | { return _PyFloat_Unpack4((const unsigned char *)p, le); } |
517 | |
518 | PYCAPI_COMPAT_STATIC_INLINE(double) |
519 | PyFloat_Unpack8(const char *p, int le) |
520 | { return _PyFloat_Unpack8((const unsigned char *)p, le); } |
521 | #endif |
522 | |
523 | |
524 | // gh-92154 added PyCode_GetCode() to Python 3.11.0b1 |
525 | #if PY_VERSION_HEX < 0x030B00B1 && !defined(PYPY_VERSION) |
526 | PYCAPI_COMPAT_STATIC_INLINE(PyObject*) |
527 | PyCode_GetCode(PyCodeObject *code) |
528 | { |
529 | return Py_NewRef(code->co_code); |
530 | } |
531 | #endif |
532 | |
533 | |
534 | // gh-95008 added PyCode_GetVarnames() to Python 3.11.0rc1 |
535 | #if PY_VERSION_HEX < 0x030B00C1 && !defined(PYPY_VERSION) |
536 | PYCAPI_COMPAT_STATIC_INLINE(PyObject*) |
537 | PyCode_GetVarnames(PyCodeObject *code) |
538 | { |
539 | return Py_NewRef(code->co_varnames); |
540 | } |
541 | #endif |
542 | |
543 | // gh-95008 added PyCode_GetFreevars() to Python 3.11.0rc1 |
544 | #if PY_VERSION_HEX < 0x030B00C1 && !defined(PYPY_VERSION) |
545 | PYCAPI_COMPAT_STATIC_INLINE(PyObject*) |
546 | PyCode_GetFreevars(PyCodeObject *code) |
547 | { |
548 | return Py_NewRef(code->co_freevars); |
549 | } |
550 | #endif |
551 | |
552 | // gh-95008 added PyCode_GetCellvars() to Python 3.11.0rc1 |
553 | #if PY_VERSION_HEX < 0x030B00C1 && !defined(PYPY_VERSION) |
554 | PYCAPI_COMPAT_STATIC_INLINE(PyObject*) |
555 | PyCode_GetCellvars(PyCodeObject *code) |
556 | { |
557 | return Py_NewRef(code->co_cellvars); |
558 | } |
559 | #endif |
560 | |
561 | |
562 | // Py_UNUSED() was added to Python 3.4.0b2. |
563 | #if PY_VERSION_HEX < 0x030400B2 && !defined(Py_UNUSED) |
564 | # if defined(__GNUC__) || defined(__clang__) |
565 | # define Py_UNUSED(name) _unused_ ## name __attribute__((unused)) |
566 | # else |
567 | # define Py_UNUSED(name) _unused_ ## name |
568 | # endif |
569 | #endif |
570 | |
571 | |
572 | #ifdef __cplusplus |
573 | } |
574 | #endif |
575 | #endif // PYTHONCAPI_COMPAT |