From 35933b3ed7bfdab377d2418f3c566053ebbca87e Mon Sep 17 00:00:00 2001 From: Alexander Shadchin Date: Sun, 14 Aug 2022 21:13:49 +0300 Subject: [PATCH] Fix build with Python 3.11 The PyFrameObject structure members have been removed from the public C API. --- python/google/protobuf/pyext/descriptor.cc | 45 ++++++++++++++++++++-- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/python/google/protobuf/pyext/descriptor.cc b/python/google/protobuf/pyext/descriptor.cc index 75f1760ccf45..951ba46bce55 100644 --- a/python/google/protobuf/pyext/descriptor.cc +++ b/python/google/protobuf/pyext/descriptor.cc @@ -63,6 +63,43 @@ : PyBytes_AsStringAndSize(ob, (charpp), (sizep))) #endif +#if PY_VERSION_HEX < 0x030900B1 && !defined(PYPY_VERSION) +static inline PyCodeObject* PyFrame_GetCode(PyFrameObject *frame) +{ + Py_INCREF(frame->f_code); + return frame->f_code; +} + +static inline PyFrameObject* PyFrame_GetBack(PyFrameObject *frame) +{ + Py_XINCREF(frame->f_back); + return frame->f_back; +} +#endif + +#if PY_VERSION_HEX < 0x030B00A7 && !defined(PYPY_VERSION) +static inline PyObject* PyFrame_GetLocals(PyFrameObject *frame) +{ +#if PY_VERSION_HEX >= 0x030400B1 + if (PyFrame_FastToLocalsWithError(frame) < 0) { + return NULL; + } +#else + PyFrame_FastToLocals(frame); +#endif + Py_INCREF(frame->f_locals); + return frame->f_locals; +} +#endif + +#if PY_VERSION_HEX < 0x030B00A7 && !defined(PYPY_VERSION) +static inline PyObject* PyFrame_GetGlobals(PyFrameObject *frame) +{ + Py_INCREF(frame->f_globals); + return frame->f_globals; +} +#endif + namespace google { namespace protobuf { namespace python { @@ -105,18 +142,18 @@ bool _CalledFromGeneratedFile(int stacklevel) { return false; } while (stacklevel-- > 0) { - frame = frame->f_back; + frame = PyFrame_GetBack(frame); if (frame == NULL) { return false; } } - if (frame->f_code->co_filename == NULL) { + if (PyFrame_GetCode(frame)->co_filename == NULL) { return false; } char* filename; Py_ssize_t filename_size; - if (PyString_AsStringAndSize(frame->f_code->co_filename, + if (PyString_AsStringAndSize(PyFrame_GetCode(frame)->co_filename, &filename, &filename_size) < 0) { // filename is not a string. PyErr_Clear(); @@ -137,7 +174,7 @@ bool _CalledFromGeneratedFile(int stacklevel) { return false; } - if (frame->f_globals != frame->f_locals) { + if (PyFrame_GetGlobals(frame) != PyFrame_GetLocals(frame)) { // Not at global module scope return false; }