Skip to content

Commit

Permalink
Fix build with Python 3.11
Browse files Browse the repository at this point in the history
The PyFrameObject structure members have been removed from the public C API.
  • Loading branch information
shadchin committed Sep 11, 2022
1 parent fcd26be commit 4428a36
Showing 1 changed file with 68 additions and 13 deletions.
81 changes: 68 additions & 13 deletions python/google/protobuf/pyext/descriptor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,43 @@
: 0) \
: PyBytes_AsStringAndSize(ob, (charpp), (sizep)))

#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 {
Expand Down Expand Up @@ -96,48 +133,66 @@ bool _CalledFromGeneratedFile(int stacklevel) {
// This check is not critical and is somewhat difficult to implement correctly
// in PyPy.
PyFrameObject* frame = PyEval_GetFrame();
PyCodeObject* frame_code = nullptr;
PyObject* frame_globals = nullptr;
PyObject* frame_locals = nullptr;
bool result = false;

if (frame == nullptr) {
return false;
goto exit;
}
Py_INCREF(frame);
while (stacklevel-- > 0) {
frame = frame->f_back;
PyFrameObject* next_frame = PyFrame_GetBack(frame);
Py_DECREF(frame);
frame = next_frame;
if (frame == nullptr) {
return false;
goto exit;
}
}

if (frame->f_code->co_filename == nullptr) {
return false;
frame_code = PyFrame_GetCode(frame);
if (frame_code->co_filename == nullptr) {
goto exit;
}
char* filename;
Py_ssize_t filename_size;
if (PyString_AsStringAndSize(frame->f_code->co_filename,
if (PyString_AsStringAndSize(frame_code->co_filename,
&filename, &filename_size) < 0) {
// filename is not a string.
PyErr_Clear();
return false;
goto exit;
}
if ((filename_size < 3) ||
(strcmp(&filename[filename_size - 3], ".py") != 0)) {
// Cython's stack does not have .py file name and is not at global module
// scope.
return true;
result = true;
goto exit;
}
if (filename_size < 7) {
// filename is too short.
return false;
goto exit;
}
if (strcmp(&filename[filename_size - 7], "_pb2.py") != 0) {
// Filename is not ending with _pb2.
return false;
goto exit;
}

if (frame->f_globals != frame->f_locals) {
frame_globals = PyFrame_GetGlobals(frame);
frame_locals = PyFrame_GetLocals(frame);
if (frame_globals != frame_locals) {
// Not at global module scope
return false;
goto exit;
}
#endif
return true;
result = true;
exit:
Py_XDECREF(frame_globals);
Py_XDECREF(frame_locals);
Py_XDECREF(frame_code);
Py_XDECREF(frame);
return result;
}

// If the calling code is not a _pb2.py file, raise AttributeError.
Expand Down

0 comments on commit 4428a36

Please sign in to comment.