Skip to content

Commit 291c39d

Browse files
Sync pythoncapi_compat.h (#12859)
1 parent 040f3ab commit 291c39d

File tree

1 file changed

+158
-68
lines changed

1 file changed

+158
-68
lines changed

mypyc/lib-rt/pythoncapi_compat.h

Lines changed: 158 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44
// Copyright Contributors to the pythoncapi_compat project.
55
//
66
// Homepage:
7-
// https://github.com/pythoncapi/pythoncapi_compat
7+
// https://github.com/python/pythoncapi_compat
88
//
99
// Latest version:
10-
// https://raw.githubusercontent.com/pythoncapi/pythoncapi_compat/master/pythoncapi_compat.h
10+
// https://raw.githubusercontent.com/python/pythoncapi_compat/master/pythoncapi_compat.h
1111
//
1212
// SPDX-License-Identifier: 0BSD
1313

@@ -26,27 +26,32 @@ extern "C" {
2626
// the inline keyword in C (only in C++): use __inline instead.
2727
#if (defined(_MSC_VER) && _MSC_VER < 1900 \
2828
&& !defined(__cplusplus) && !defined(inline))
29-
# define PYCAPI_COMPAT_INLINE(TYPE static __inline TYPE
29+
# define PYCAPI_COMPAT_STATIC_INLINE(TYPE) static __inline TYPE
3030
#else
3131
# define PYCAPI_COMPAT_STATIC_INLINE(TYPE) static inline TYPE
3232
#endif
3333

3434

35-
// C++ compatibility
36-
#ifdef __cplusplus
37-
# define PYCAPI_COMPAT_CAST(TYPE, EXPR) reinterpret_cast<TYPE>(EXPR)
38-
# define PYCAPI_COMPAT_NULL nullptr
39-
#else
40-
# define PYCAPI_COMPAT_CAST(TYPE, EXPR) (TYPE)(EXPR)
41-
# define PYCAPI_COMPAT_NULL NULL
35+
// C++ compatibility: _Py_CAST() and _Py_NULL
36+
#ifndef _Py_CAST
37+
# ifdef __cplusplus
38+
# define _Py_CAST(type, expr) \
39+
const_cast<type>(reinterpret_cast<const type>(expr))
40+
# else
41+
# define _Py_CAST(type, expr) ((type)(expr))
42+
# endif
43+
#endif
44+
#ifndef _Py_NULL
45+
# ifdef __cplusplus
46+
# define _Py_NULL nullptr
47+
# else
48+
# define _Py_NULL NULL
49+
# endif
4250
#endif
4351

4452
// Cast argument to PyObject* type.
4553
#ifndef _PyObject_CAST
46-
# define _PyObject_CAST(op) PYCAPI_COMPAT_CAST(PyObject*, op)
47-
#endif
48-
#ifndef _PyObject_CAST_CONST
49-
# define _PyObject_CAST_CONST(op) PYCAPI_COMPAT_CAST(const PyObject*, op)
54+
# define _PyObject_CAST(op) _Py_CAST(PyObject*, op)
5055
#endif
5156

5257

@@ -74,30 +79,6 @@ _Py_XNewRef(PyObject *obj)
7479
#endif
7580

7681

77-
// See https://bugs.python.org/issue42522
78-
#if !defined(_Py_StealRef)
79-
PYCAPI_COMPAT_STATIC_INLINE(PyObject*)
80-
__Py_StealRef(PyObject *obj)
81-
{
82-
Py_DECREF(obj);
83-
return obj;
84-
}
85-
#define _Py_StealRef(obj) __Py_StealRef(_PyObject_CAST(obj))
86-
#endif
87-
88-
89-
// See https://bugs.python.org/issue42522
90-
#if !defined(_Py_XStealRef)
91-
PYCAPI_COMPAT_STATIC_INLINE(PyObject*)
92-
__Py_XStealRef(PyObject *obj)
93-
{
94-
Py_XDECREF(obj);
95-
return obj;
96-
}
97-
#define _Py_XStealRef(obj) __Py_XStealRef(_PyObject_CAST(obj))
98-
#endif
99-
100-
10182
// bpo-39573 added Py_SET_REFCNT() to Python 3.9.0a4
10283
#if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_REFCNT)
10384
PYCAPI_COMPAT_STATIC_INLINE(void)
@@ -171,36 +152,95 @@ _Py_SET_SIZE(PyVarObject *ob, Py_ssize_t size)
171152
PYCAPI_COMPAT_STATIC_INLINE(PyCodeObject*)
172153
PyFrame_GetCode(PyFrameObject *frame)
173154
{
174-
assert(frame != PYCAPI_COMPAT_NULL);
175-
assert(frame->f_code != PYCAPI_COMPAT_NULL);
176-
return PYCAPI_COMPAT_CAST(PyCodeObject*, Py_NewRef(frame->f_code));
155+
assert(frame != _Py_NULL);
156+
assert(frame->f_code != _Py_NULL);
157+
return _Py_CAST(PyCodeObject*, Py_NewRef(frame->f_code));
177158
}
178159
#endif
179160

180161
PYCAPI_COMPAT_STATIC_INLINE(PyCodeObject*)
181162
_PyFrame_GetCodeBorrow(PyFrameObject *frame)
182163
{
183-
return PYCAPI_COMPAT_CAST(PyCodeObject *,
184-
_Py_StealRef(PyFrame_GetCode(frame)));
164+
PyCodeObject *code = PyFrame_GetCode(frame);
165+
Py_DECREF(code);
166+
return code;
185167
}
186168

187169

188-
// bpo-40421 added PyFrame_GetCode() to Python 3.9.0b1
170+
// bpo-40421 added PyFrame_GetBack() to Python 3.9.0b1
189171
#if PY_VERSION_HEX < 0x030900B1 && !defined(PYPY_VERSION)
190172
PYCAPI_COMPAT_STATIC_INLINE(PyFrameObject*)
191173
PyFrame_GetBack(PyFrameObject *frame)
192174
{
193-
assert(frame != PYCAPI_COMPAT_NULL);
194-
return PYCAPI_COMPAT_CAST(PyFrameObject*, Py_XNewRef(frame->f_back));
175+
assert(frame != _Py_NULL);
176+
return _Py_CAST(PyFrameObject*, Py_XNewRef(frame->f_back));
195177
}
196178
#endif
197179

198180
#if !defined(PYPY_VERSION)
199181
PYCAPI_COMPAT_STATIC_INLINE(PyFrameObject*)
200182
_PyFrame_GetBackBorrow(PyFrameObject *frame)
201183
{
202-
return PYCAPI_COMPAT_CAST(PyFrameObject *,
203-
_Py_XStealRef(PyFrame_GetBack(frame)));
184+
PyFrameObject *back = PyFrame_GetBack(frame);
185+
Py_XDECREF(back);
186+
return back;
187+
}
188+
#endif
189+
190+
191+
// bpo-40421 added PyFrame_GetLocals() to Python 3.11.0a7
192+
#if PY_VERSION_HEX < 0x030B00A7 && !defined(PYPY_VERSION)
193+
PYCAPI_COMPAT_STATIC_INLINE(PyObject*)
194+
PyFrame_GetLocals(PyFrameObject *frame)
195+
{
196+
#if PY_VERSION_HEX >= 0x030400B1
197+
if (PyFrame_FastToLocalsWithError(frame) < 0) {
198+
return NULL;
199+
}
200+
#else
201+
PyFrame_FastToLocals(frame);
202+
#endif
203+
return Py_NewRef(frame->f_locals);
204+
}
205+
#endif
206+
207+
208+
// bpo-40421 added PyFrame_GetGlobals() to Python 3.11.0a7
209+
#if PY_VERSION_HEX < 0x030B00A7 && !defined(PYPY_VERSION)
210+
PYCAPI_COMPAT_STATIC_INLINE(PyObject*)
211+
PyFrame_GetGlobals(PyFrameObject *frame)
212+
{
213+
return Py_NewRef(frame->f_globals);
214+
}
215+
#endif
216+
217+
218+
// bpo-40421 added PyFrame_GetBuiltins() to Python 3.11.0a7
219+
#if PY_VERSION_HEX < 0x030B00A7 && !defined(PYPY_VERSION)
220+
PYCAPI_COMPAT_STATIC_INLINE(PyObject*)
221+
PyFrame_GetBuiltins(PyFrameObject *frame)
222+
{
223+
return Py_NewRef(frame->f_builtins);
224+
}
225+
#endif
226+
227+
228+
// bpo-40421 added PyFrame_GetLasti() to Python 3.11.0b1
229+
#if PY_VERSION_HEX < 0x030B00B1 && !defined(PYPY_VERSION)
230+
PYCAPI_COMPAT_STATIC_INLINE(int)
231+
PyFrame_GetLasti(PyFrameObject *frame)
232+
{
233+
#if PY_VERSION_HEX >= 0x030A00A7
234+
// bpo-27129: Since Python 3.10.0a7, f_lasti is an instruction offset,
235+
// not a bytes offset anymore. Python uses 16-bit "wordcode" (2 bytes)
236+
// instructions.
237+
if (frame->f_lasti < 0) {
238+
return -1;
239+
}
240+
return frame->f_lasti * 2;
241+
#else
242+
return frame->f_lasti;
243+
#endif
204244
}
205245
#endif
206246

@@ -210,7 +250,7 @@ _PyFrame_GetBackBorrow(PyFrameObject *frame)
210250
PYCAPI_COMPAT_STATIC_INLINE(PyInterpreterState *)
211251
PyThreadState_GetInterpreter(PyThreadState *tstate)
212252
{
213-
assert(tstate != PYCAPI_COMPAT_NULL);
253+
assert(tstate != _Py_NULL);
214254
return tstate->interp;
215255
}
216256
#endif
@@ -221,17 +261,18 @@ PyThreadState_GetInterpreter(PyThreadState *tstate)
221261
PYCAPI_COMPAT_STATIC_INLINE(PyFrameObject*)
222262
PyThreadState_GetFrame(PyThreadState *tstate)
223263
{
224-
assert(tstate != PYCAPI_COMPAT_NULL);
225-
return PYCAPI_COMPAT_CAST(PyFrameObject *, Py_XNewRef(tstate->frame));
264+
assert(tstate != _Py_NULL);
265+
return _Py_CAST(PyFrameObject *, Py_XNewRef(tstate->frame));
226266
}
227267
#endif
228268

229269
#if !defined(PYPY_VERSION)
230270
PYCAPI_COMPAT_STATIC_INLINE(PyFrameObject*)
231271
_PyThreadState_GetFrameBorrow(PyThreadState *tstate)
232272
{
233-
return PYCAPI_COMPAT_CAST(PyFrameObject*,
234-
_Py_XStealRef(PyThreadState_GetFrame(tstate)));
273+
PyFrameObject *frame = PyThreadState_GetFrame(tstate);
274+
Py_XDECREF(frame);
275+
return frame;
235276
}
236277
#endif
237278

@@ -245,11 +286,11 @@ PyInterpreterState_Get(void)
245286
PyInterpreterState *interp;
246287

247288
tstate = PyThreadState_GET();
248-
if (tstate == PYCAPI_COMPAT_NULL) {
289+
if (tstate == _Py_NULL) {
249290
Py_FatalError("GIL released (tstate is NULL)");
250291
}
251292
interp = tstate->interp;
252-
if (interp == PYCAPI_COMPAT_NULL) {
293+
if (interp == _Py_NULL) {
253294
Py_FatalError("no current interpreter");
254295
}
255296
return interp;
@@ -262,7 +303,7 @@ PyInterpreterState_Get(void)
262303
PYCAPI_COMPAT_STATIC_INLINE(uint64_t)
263304
PyThreadState_GetID(PyThreadState *tstate)
264305
{
265-
assert(tstate != PYCAPI_COMPAT_NULL);
306+
assert(tstate != _Py_NULL);
266307
return tstate->id;
267308
}
268309
#endif
@@ -286,8 +327,8 @@ PyThreadState_EnterTracing(PyThreadState *tstate)
286327
PYCAPI_COMPAT_STATIC_INLINE(void)
287328
PyThreadState_LeaveTracing(PyThreadState *tstate)
288329
{
289-
int use_tracing = (tstate->c_tracefunc != PYCAPI_COMPAT_NULL
290-
|| tstate->c_profilefunc != PYCAPI_COMPAT_NULL);
330+
int use_tracing = (tstate->c_tracefunc != _Py_NULL
331+
|| tstate->c_profilefunc != _Py_NULL);
291332
tstate->tracing--;
292333
#if PY_VERSION_HEX >= 0x030A00A1
293334
tstate->cframe->use_tracing = use_tracing;
@@ -322,11 +363,11 @@ PyObject_CallOneArg(PyObject *func, PyObject *arg)
322363
// bpo-1635741 added PyModule_AddObjectRef() to Python 3.10.0a3
323364
#if PY_VERSION_HEX < 0x030A00A3
324365
PYCAPI_COMPAT_STATIC_INLINE(int)
325-
PyModule_AddObjectRef(PyObject *mod, const char *name, PyObject *value)
366+
PyModule_AddObjectRef(PyObject *module, const char *name, PyObject *value)
326367
{
327368
int res;
328369
Py_XINCREF(value);
329-
res = PyModule_AddObject(mod, name, value);
370+
res = PyModule_AddObject(module, name, value);
330371
if (res < 0) {
331372
Py_XDECREF(value);
332373
}
@@ -338,7 +379,7 @@ PyModule_AddObjectRef(PyObject *mod, const char *name, PyObject *value)
338379
// bpo-40024 added PyModule_AddType() to Python 3.9.0a5
339380
#if PY_VERSION_HEX < 0x030900A5
340381
PYCAPI_COMPAT_STATIC_INLINE(int)
341-
PyModule_AddType(PyObject *mod, PyTypeObject *type)
382+
PyModule_AddType(PyObject *module, PyTypeObject *type)
342383
{
343384
const char *name, *dot;
344385

@@ -348,13 +389,13 @@ PyModule_AddType(PyObject *mod, PyTypeObject *type)
348389

349390
// inline _PyType_Name()
350391
name = type->tp_name;
351-
assert(name != PYCAPI_COMPAT_NULL);
392+
assert(name != _Py_NULL);
352393
dot = strrchr(name, '.');
353-
if (dot != PYCAPI_COMPAT_NULL) {
394+
if (dot != _Py_NULL) {
354395
name = dot + 1;
355396
}
356397

357-
return PyModule_AddObjectRef(mod, name, _PyObject_CAST(type));
398+
return PyModule_AddObjectRef(module, name, _PyObject_CAST(type));
358399
}
359400
#endif
360401

@@ -375,7 +416,7 @@ PyObject_GC_IsTracked(PyObject* obj)
375416
PYCAPI_COMPAT_STATIC_INLINE(int)
376417
PyObject_GC_IsFinalized(PyObject *obj)
377418
{
378-
PyGC_Head *gc = PYCAPI_COMPAT_CAST(PyGC_Head *, obj) - 1;
419+
PyGC_Head *gc = _Py_CAST(PyGC_Head*, obj) - 1;
379420
return (PyObject_IS_GC(obj) && _PyGCHead_FINALIZED(gc));
380421
}
381422
#endif
@@ -384,10 +425,59 @@ PyObject_GC_IsFinalized(PyObject *obj)
384425
// bpo-39573 added Py_IS_TYPE() to Python 3.9.0a4
385426
#if PY_VERSION_HEX < 0x030900A4 && !defined(Py_IS_TYPE)
386427
PYCAPI_COMPAT_STATIC_INLINE(int)
387-
_Py_IS_TYPE(const PyObject *ob, const PyTypeObject *type) {
388-
return ob->ob_type == type;
428+
_Py_IS_TYPE(PyObject *ob, PyTypeObject *type) {
429+
return Py_TYPE(ob) == type;
430+
}
431+
#define Py_IS_TYPE(ob, type) _Py_IS_TYPE(_PyObject_CAST(ob), type)
432+
#endif
433+
434+
435+
// bpo-46906 added PyFloat_Pack2() and PyFloat_Unpack2() to Python 3.11a7.
436+
// bpo-11734 added _PyFloat_Pack2() and _PyFloat_Unpack2() to Python 3.6.0b1.
437+
// Python 3.11a2 moved _PyFloat_Pack2() and _PyFloat_Unpack2() to the internal
438+
// C API: Python 3.11a2-3.11a6 versions are not supported.
439+
#if 0x030600B1 <= PY_VERSION_HEX && PY_VERSION_HEX <= 0x030B00A1 && !defined(PYPY_VERSION)
440+
PYCAPI_COMPAT_STATIC_INLINE(int)
441+
PyFloat_Pack2(double x, char *p, int le)
442+
{ return _PyFloat_Pack2(x, (unsigned char*)p, le); }
443+
444+
PYCAPI_COMPAT_STATIC_INLINE(double)
445+
PyFloat_Unpack2(const char *p, int le)
446+
{ return _PyFloat_Unpack2((const unsigned char *)p, le); }
447+
#endif
448+
449+
450+
// bpo-46906 added PyFloat_Pack4(), PyFloat_Pack8(), PyFloat_Unpack4() and
451+
// PyFloat_Unpack8() to Python 3.11a7.
452+
// Python 3.11a2 moved _PyFloat_Pack4(), _PyFloat_Pack8(), _PyFloat_Unpack4()
453+
// and _PyFloat_Unpack8() to the internal C API: Python 3.11a2-3.11a6 versions
454+
// are not supported.
455+
#if PY_VERSION_HEX <= 0x030B00A1 && !defined(PYPY_VERSION)
456+
PYCAPI_COMPAT_STATIC_INLINE(int)
457+
PyFloat_Pack4(double x, char *p, int le)
458+
{ return _PyFloat_Pack4(x, (unsigned char*)p, le); }
459+
460+
PYCAPI_COMPAT_STATIC_INLINE(int)
461+
PyFloat_Pack8(double x, char *p, int le)
462+
{ return _PyFloat_Pack8(x, (unsigned char*)p, le); }
463+
464+
PYCAPI_COMPAT_STATIC_INLINE(double)
465+
PyFloat_Unpack4(const char *p, int le)
466+
{ return _PyFloat_Unpack4((const unsigned char *)p, le); }
467+
468+
PYCAPI_COMPAT_STATIC_INLINE(double)
469+
PyFloat_Unpack8(const char *p, int le)
470+
{ return _PyFloat_Unpack8((const unsigned char *)p, le); }
471+
#endif
472+
473+
474+
// gh-92154 added PyCode_GetCode() to Python 3.11.0b1
475+
#if PY_VERSION_HEX < 0x030B00B1 && !defined(PYPY_VERSION)
476+
PYCAPI_COMPAT_STATIC_INLINE(PyObject*)
477+
PyCode_GetCode(PyCodeObject *code)
478+
{
479+
return Py_NewRef(code->co_code);
389480
}
390-
#define Py_IS_TYPE(ob, type) _Py_IS_TYPE(_PyObject_CAST_CONST(ob), type)
391481
#endif
392482

393483

0 commit comments

Comments
 (0)