diff --git a/contrib/clang-format-ignorelist b/contrib/clang-format-ignorelist --- a/contrib/clang-format-ignorelist +++ b/contrib/clang-format-ignorelist @@ -9,3 +9,4 @@ hgext/fsmonitor/pywatchman/**.c mercurial/thirdparty/**.c mercurial/thirdparty/**.h +mercurial/pythoncapi_compat.h diff --git a/contrib/python-zstandard/c-ext/bufferutil.c b/contrib/python-zstandard/c-ext/bufferutil.c --- a/contrib/python-zstandard/c-ext/bufferutil.c +++ b/contrib/python-zstandard/c-ext/bufferutil.c @@ -758,7 +758,7 @@ }; void bufferutil_module_init(PyObject* mod) { - Py_TYPE(&ZstdBufferWithSegmentsType) = &PyType_Type; + Py_SET_TYPE(&ZstdBufferWithSegmentsType, &PyType_Type); if (PyType_Ready(&ZstdBufferWithSegmentsType) < 0) { return; } @@ -766,7 +766,7 @@ Py_INCREF(&ZstdBufferWithSegmentsType); PyModule_AddObject(mod, "BufferWithSegments", (PyObject*)&ZstdBufferWithSegmentsType); - Py_TYPE(&ZstdBufferSegmentsType) = &PyType_Type; + Py_SET_TYPE(&ZstdBufferSegmentsType, &PyType_Type); if (PyType_Ready(&ZstdBufferSegmentsType) < 0) { return; } @@ -774,7 +774,7 @@ Py_INCREF(&ZstdBufferSegmentsType); PyModule_AddObject(mod, "BufferSegments", (PyObject*)&ZstdBufferSegmentsType); - Py_TYPE(&ZstdBufferSegmentType) = &PyType_Type; + Py_SET_TYPE(&ZstdBufferSegmentType, &PyType_Type); if (PyType_Ready(&ZstdBufferSegmentType) < 0) { return; } @@ -782,7 +782,7 @@ Py_INCREF(&ZstdBufferSegmentType); PyModule_AddObject(mod, "BufferSegment", (PyObject*)&ZstdBufferSegmentType); - Py_TYPE(&ZstdBufferWithSegmentsCollectionType) = &PyType_Type; + Py_SET_TYPE(&ZstdBufferWithSegmentsCollectionType, &PyType_Type); if (PyType_Ready(&ZstdBufferWithSegmentsCollectionType) < 0) { return; } diff --git a/contrib/python-zstandard/c-ext/compressionchunker.c b/contrib/python-zstandard/c-ext/compressionchunker.c --- a/contrib/python-zstandard/c-ext/compressionchunker.c +++ b/contrib/python-zstandard/c-ext/compressionchunker.c @@ -348,12 +348,12 @@ }; void compressionchunker_module_init(PyObject* module) { - Py_TYPE(&ZstdCompressionChunkerIteratorType) = &PyType_Type; + Py_SET_TYPE(&ZstdCompressionChunkerIteratorType, &PyType_Type); if (PyType_Ready(&ZstdCompressionChunkerIteratorType) < 0) { return; } - Py_TYPE(&ZstdCompressionChunkerType) = &PyType_Type; + Py_SET_TYPE(&ZstdCompressionChunkerType, &PyType_Type); if (PyType_Ready(&ZstdCompressionChunkerType) < 0) { return; } diff --git a/contrib/python-zstandard/c-ext/compressiondict.c b/contrib/python-zstandard/c-ext/compressiondict.c --- a/contrib/python-zstandard/c-ext/compressiondict.c +++ b/contrib/python-zstandard/c-ext/compressiondict.c @@ -400,7 +400,7 @@ }; void compressiondict_module_init(PyObject* mod) { - Py_TYPE(&ZstdCompressionDictType) = &PyType_Type; + Py_SET_TYPE(&ZstdCompressionDictType, &PyType_Type); if (PyType_Ready(&ZstdCompressionDictType) < 0) { return; } diff --git a/contrib/python-zstandard/c-ext/compressionparams.c b/contrib/python-zstandard/c-ext/compressionparams.c --- a/contrib/python-zstandard/c-ext/compressionparams.c +++ b/contrib/python-zstandard/c-ext/compressionparams.c @@ -556,7 +556,7 @@ }; void compressionparams_module_init(PyObject* mod) { - Py_TYPE(&ZstdCompressionParametersType) = &PyType_Type; + Py_SET_TYPE(&ZstdCompressionParametersType, &PyType_Type); if (PyType_Ready(&ZstdCompressionParametersType) < 0) { return; } diff --git a/contrib/python-zstandard/c-ext/compressionreader.c b/contrib/python-zstandard/c-ext/compressionreader.c --- a/contrib/python-zstandard/c-ext/compressionreader.c +++ b/contrib/python-zstandard/c-ext/compressionreader.c @@ -811,7 +811,7 @@ void compressionreader_module_init(PyObject* mod) { /* TODO make reader a sub-class of io.RawIOBase */ - Py_TYPE(&ZstdCompressionReaderType) = &PyType_Type; + Py_SET_TYPE(&ZstdCompressionReaderType, &PyType_Type); if (PyType_Ready(&ZstdCompressionReaderType) < 0) { return; } diff --git a/contrib/python-zstandard/c-ext/compressionwriter.c b/contrib/python-zstandard/c-ext/compressionwriter.c --- a/contrib/python-zstandard/c-ext/compressionwriter.c +++ b/contrib/python-zstandard/c-ext/compressionwriter.c @@ -365,7 +365,7 @@ }; void compressionwriter_module_init(PyObject* mod) { - Py_TYPE(&ZstdCompressionWriterType) = &PyType_Type; + Py_SET_TYPE(&ZstdCompressionWriterType, &PyType_Type); if (PyType_Ready(&ZstdCompressionWriterType) < 0) { return; } diff --git a/contrib/python-zstandard/c-ext/compressobj.c b/contrib/python-zstandard/c-ext/compressobj.c --- a/contrib/python-zstandard/c-ext/compressobj.c +++ b/contrib/python-zstandard/c-ext/compressobj.c @@ -249,7 +249,7 @@ }; void compressobj_module_init(PyObject* module) { - Py_TYPE(&ZstdCompressionObjType) = &PyType_Type; + Py_SET_TYPE(&ZstdCompressionObjType, &PyType_Type); if (PyType_Ready(&ZstdCompressionObjType) < 0) { return; } diff --git a/contrib/python-zstandard/c-ext/compressor.c b/contrib/python-zstandard/c-ext/compressor.c --- a/contrib/python-zstandard/c-ext/compressor.c +++ b/contrib/python-zstandard/c-ext/compressor.c @@ -619,7 +619,7 @@ goto finally; } - Py_SIZE(output) = outBuffer.pos; + Py_SET_SIZE(output, outBuffer.pos); finally: PyBuffer_Release(&source); @@ -1659,7 +1659,7 @@ }; void compressor_module_init(PyObject* mod) { - Py_TYPE(&ZstdCompressorType) = &PyType_Type; + Py_SET_TYPE(&ZstdCompressorType, &PyType_Type); if (PyType_Ready(&ZstdCompressorType) < 0) { return; } diff --git a/contrib/python-zstandard/c-ext/compressoriterator.c b/contrib/python-zstandard/c-ext/compressoriterator.c --- a/contrib/python-zstandard/c-ext/compressoriterator.c +++ b/contrib/python-zstandard/c-ext/compressoriterator.c @@ -228,7 +228,7 @@ }; void compressoriterator_module_init(PyObject* mod) { - Py_TYPE(&ZstdCompressorIteratorType) = &PyType_Type; + Py_SET_TYPE(&ZstdCompressorIteratorType, &PyType_Type); if (PyType_Ready(&ZstdCompressorIteratorType) < 0) { return; } diff --git a/contrib/python-zstandard/c-ext/decompressionreader.c b/contrib/python-zstandard/c-ext/decompressionreader.c --- a/contrib/python-zstandard/c-ext/decompressionreader.c +++ b/contrib/python-zstandard/c-ext/decompressionreader.c @@ -774,7 +774,7 @@ void decompressionreader_module_init(PyObject* mod) { /* TODO make reader a sub-class of io.RawIOBase */ - Py_TYPE(&ZstdDecompressionReaderType) = &PyType_Type; + Py_SET_TYPE(&ZstdDecompressionReaderType, &PyType_Type); if (PyType_Ready(&ZstdDecompressionReaderType) < 0) { return; } diff --git a/contrib/python-zstandard/c-ext/decompressionwriter.c b/contrib/python-zstandard/c-ext/decompressionwriter.c --- a/contrib/python-zstandard/c-ext/decompressionwriter.c +++ b/contrib/python-zstandard/c-ext/decompressionwriter.c @@ -288,7 +288,7 @@ }; void decompressionwriter_module_init(PyObject* mod) { - Py_TYPE(&ZstdDecompressionWriterType) = &PyType_Type; + Py_SET_TYPE(&ZstdDecompressionWriterType, &PyType_Type); if (PyType_Ready(&ZstdDecompressionWriterType) < 0) { return; } diff --git a/contrib/python-zstandard/c-ext/decompressobj.c b/contrib/python-zstandard/c-ext/decompressobj.c --- a/contrib/python-zstandard/c-ext/decompressobj.c +++ b/contrib/python-zstandard/c-ext/decompressobj.c @@ -195,7 +195,7 @@ }; void decompressobj_module_init(PyObject* module) { - Py_TYPE(&ZstdDecompressionObjType) = &PyType_Type; + Py_SET_TYPE(&ZstdDecompressionObjType, &PyType_Type); if (PyType_Ready(&ZstdDecompressionObjType) < 0) { return; } diff --git a/contrib/python-zstandard/c-ext/decompressor.c b/contrib/python-zstandard/c-ext/decompressor.c --- a/contrib/python-zstandard/c-ext/decompressor.c +++ b/contrib/python-zstandard/c-ext/decompressor.c @@ -1811,7 +1811,7 @@ }; void decompressor_module_init(PyObject* mod) { - Py_TYPE(&ZstdDecompressorType) = &PyType_Type; + Py_SET_TYPE(&ZstdDecompressorType, &PyType_Type); if (PyType_Ready(&ZstdDecompressorType) < 0) { return; } diff --git a/contrib/python-zstandard/c-ext/decompressoriterator.c b/contrib/python-zstandard/c-ext/decompressoriterator.c --- a/contrib/python-zstandard/c-ext/decompressoriterator.c +++ b/contrib/python-zstandard/c-ext/decompressoriterator.c @@ -242,7 +242,7 @@ }; void decompressoriterator_module_init(PyObject* mod) { - Py_TYPE(&ZstdDecompressorIteratorType) = &PyType_Type; + Py_SET_TYPE(&ZstdDecompressorIteratorType, &PyType_Type); if (PyType_Ready(&ZstdDecompressorIteratorType) < 0) { return; } diff --git a/contrib/python-zstandard/c-ext/frameparams.c b/contrib/python-zstandard/c-ext/frameparams.c --- a/contrib/python-zstandard/c-ext/frameparams.c +++ b/contrib/python-zstandard/c-ext/frameparams.c @@ -128,7 +128,7 @@ }; void frameparams_module_init(PyObject* mod) { - Py_TYPE(&FrameParametersType) = &PyType_Type; + Py_SET_TYPE(&FrameParametersType, &PyType_Type); if (PyType_Ready(&FrameParametersType) < 0) { return; } diff --git a/contrib/python-zstandard/c-ext/python-zstandard.h b/contrib/python-zstandard/c-ext/python-zstandard.h --- a/contrib/python-zstandard/c-ext/python-zstandard.h +++ b/contrib/python-zstandard/c-ext/python-zstandard.h @@ -9,6 +9,7 @@ #define PY_SSIZE_T_CLEAN #include #include "structmember.h" +#include #define ZSTD_STATIC_LINKING_ONLY #define ZDICT_STATIC_LINKING_ONLY diff --git a/contrib/python-zstandard/zstd/common/pythoncapi_compat.h b/contrib/python-zstandard/zstd/common/pythoncapi_compat.h new file mode 100644 --- /dev/null +++ b/contrib/python-zstandard/zstd/common/pythoncapi_compat.h @@ -0,0 +1,278 @@ +// Header file providing new functions of the Python C API to old Python +// versions. +// +// File distributed under the MIT license. +// +// Homepage: +// https://github.com/pythoncapi/pythoncapi_compat +// +// Latest version: +// https://raw.githubusercontent.com/pythoncapi/pythoncapi_compat/master/pythoncapi_compat.h + +#ifndef PYTHONCAPI_COMPAT +#define PYTHONCAPI_COMPAT + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "frameobject.h" // PyFrameObject, PyFrame_GetBack() + + +// Cast argument to PyObject* type. +#ifndef _PyObject_CAST +# define _PyObject_CAST(op) ((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) +{ + 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) +{ + 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) +{ + ob->ob_refcnt = refcnt; +} +#define Py_SET_REFCNT(ob, refcnt) _Py_SET_REFCNT((PyObject*)(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) +{ + ob->ob_type = type; +} +#define Py_SET_TYPE(ob, type) _Py_SET_TYPE((PyObject*)(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) +{ + ob->ob_size = 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) +{ + PyCodeObject *code; + assert(frame != NULL); + code = frame->f_code; + assert(code != NULL); + Py_INCREF(code); + return code; +} +#endif + +static inline PyCodeObject* +_PyFrame_GetCodeBorrow(PyFrameObject *frame) +{ + PyCodeObject *code = PyFrame_GetCode(frame); + Py_DECREF(code); + 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) +{ + PyFrameObject *back; + assert(frame != NULL); + back = frame->f_back; + Py_XINCREF(back); + return back; +} +#endif + +static inline PyFrameObject* +_PyFrame_GetBackBorrow(PyFrameObject *frame) +{ + PyFrameObject *back = PyFrame_GetBack(frame); + Py_XDECREF(back); + 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) +{ + 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) +{ + PyFrameObject *frame; + assert(tstate != NULL); + frame = tstate->frame; + Py_XINCREF(frame); + return frame; +} +#endif + +static inline PyFrameObject* +_PyThreadState_GetFrameBorrow(PyThreadState *tstate) +{ + PyFrameObject *frame = PyThreadState_GetFrame(tstate); + Py_XDECREF(frame); + 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) +{ + PyThreadState *tstate; + PyInterpreterState *interp; + + tstate = PyThreadState_GET(); + if (tstate == NULL) { + Py_FatalError("GIL released (tstate is NULL)"); + } + interp = tstate->interp; + if (interp == NULL) { + Py_FatalError("no current interpreter"); + } + return interp; +} +#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) +{ + 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) +{ + 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) +{ + return PyObject_CallFunctionObjArgs(func, arg, NULL); +} +#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) +{ + const char *name, *dot; + + if (PyType_Ready(type) < 0) { + return -1; + } + + // inline _PyType_Name() + name = type->tp_name; + assert(name != NULL); + dot = strrchr(name, '.'); + if (dot != NULL) { + name = dot + 1; + } + + Py_INCREF(type); + if (PyModule_AddObject(module, name, (PyObject *)type) < 0) { + Py_DECREF(type); + return -1; + } + + return 0; +} +#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) +{ + 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) +{ + 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) { + return ob->ob_type == type; +} +#define Py_IS_TYPE(ob, type) _Py_IS_TYPE((const PyObject*)(ob), type) +#endif + + +#ifdef __cplusplus +} +#endif +#endif // PYTHONCAPI_COMPAT diff --git a/mercurial/cext/osutil.c b/mercurial/cext/osutil.c --- a/mercurial/cext/osutil.c +++ b/mercurial/cext/osutil.c @@ -119,7 +119,7 @@ static void listdir_stat_dealloc(PyObject *o) { - o->ob_type->tp_free(o); + Py_TYPE(o)->tp_free(o); } static PyObject *listdir_stat_getitem(PyObject *self, PyObject *key) diff --git a/mercurial/cext/pathencode.c b/mercurial/cext/pathencode.c --- a/mercurial/cext/pathencode.c +++ b/mercurial/cext/pathencode.c @@ -21,6 +21,7 @@ #include #include #include +#include "pythoncapi_compat.h" #include "util.h" @@ -678,7 +679,7 @@ } assert(PyBytes_Check(ret)); - Py_SIZE(ret) = destlen; + Py_SET_SIZE(ret, destlen); return ret; } diff --git a/mercurial/pythoncapi_compat.h b/mercurial/pythoncapi_compat.h new file mode 100644 --- /dev/null +++ b/mercurial/pythoncapi_compat.h @@ -0,0 +1,278 @@ +// Header file providing new functions of the Python C API to old Python +// versions. +// +// File distributed under the MIT license. +// +// Homepage: +// https://github.com/pythoncapi/pythoncapi_compat +// +// Latest version: +// https://raw.githubusercontent.com/pythoncapi/pythoncapi_compat/master/pythoncapi_compat.h + +#ifndef PYTHONCAPI_COMPAT +#define PYTHONCAPI_COMPAT + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "frameobject.h" // PyFrameObject, PyFrame_GetBack() + + +// Cast argument to PyObject* type. +#ifndef _PyObject_CAST +# define _PyObject_CAST(op) ((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) +{ + 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) +{ + 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) +{ + ob->ob_refcnt = refcnt; +} +#define Py_SET_REFCNT(ob, refcnt) _Py_SET_REFCNT((PyObject*)(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) +{ + ob->ob_type = type; +} +#define Py_SET_TYPE(ob, type) _Py_SET_TYPE((PyObject*)(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) +{ + ob->ob_size = 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) +{ + PyCodeObject *code; + assert(frame != NULL); + code = frame->f_code; + assert(code != NULL); + Py_INCREF(code); + return code; +} +#endif + +static inline PyCodeObject* +_PyFrame_GetCodeBorrow(PyFrameObject *frame) +{ + PyCodeObject *code = PyFrame_GetCode(frame); + Py_DECREF(code); + 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) +{ + PyFrameObject *back; + assert(frame != NULL); + back = frame->f_back; + Py_XINCREF(back); + return back; +} +#endif + +static inline PyFrameObject* +_PyFrame_GetBackBorrow(PyFrameObject *frame) +{ + PyFrameObject *back = PyFrame_GetBack(frame); + Py_XDECREF(back); + 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) +{ + 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) +{ + PyFrameObject *frame; + assert(tstate != NULL); + frame = tstate->frame; + Py_XINCREF(frame); + return frame; +} +#endif + +static inline PyFrameObject* +_PyThreadState_GetFrameBorrow(PyThreadState *tstate) +{ + PyFrameObject *frame = PyThreadState_GetFrame(tstate); + Py_XDECREF(frame); + 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) +{ + PyThreadState *tstate; + PyInterpreterState *interp; + + tstate = PyThreadState_GET(); + if (tstate == NULL) { + Py_FatalError("GIL released (tstate is NULL)"); + } + interp = tstate->interp; + if (interp == NULL) { + Py_FatalError("no current interpreter"); + } + return interp; +} +#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) +{ + 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) +{ + 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) +{ + return PyObject_CallFunctionObjArgs(func, arg, NULL); +} +#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) +{ + const char *name, *dot; + + if (PyType_Ready(type) < 0) { + return -1; + } + + // inline _PyType_Name() + name = type->tp_name; + assert(name != NULL); + dot = strrchr(name, '.'); + if (dot != NULL) { + name = dot + 1; + } + + Py_INCREF(type); + if (PyModule_AddObject(module, name, (PyObject *)type) < 0) { + Py_DECREF(type); + return -1; + } + + return 0; +} +#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) +{ + 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) +{ + 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) { + return ob->ob_type == type; +} +#define Py_IS_TYPE(ob, type) _Py_IS_TYPE((const PyObject*)(ob), type) +#endif + + +#ifdef __cplusplus +} +#endif +#endif // PYTHONCAPI_COMPAT diff --git a/tests/test-check-code.t b/tests/test-check-code.t --- a/tests/test-check-code.t +++ b/tests/test-check-code.t @@ -11,6 +11,7 @@ > -X contrib/python-zstandard \ > -X hgext/fsmonitor/pywatchman \ > -X mercurial/thirdparty \ + > -X mercurial/pythoncapi_compat.h \ > | sed 's-\\-/-g' | "$check_code" --warnings --per-file=0 - || false Skipping contrib/automation/hgautomation/__init__.py it has no-che?k-code (glob) Skipping contrib/automation/hgautomation/aws.py it has no-che?k-code (glob)