Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix build with Python 3.11 #10403

Merged
merged 1 commit into from
Sep 12, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 62 additions & 13 deletions python/google/protobuf/pyext/descriptor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,37 @@
: 0) \
: PyBytes_AsStringAndSize(ob, (charpp), (sizep)))

#if PY_VERSION_HEX < 0x030900B1 && !defined(PYPY_VERSION)
static PyCodeObject* PyFrame_GetCode(PyFrameObject *frame)
{
Py_INCREF(frame->f_code);
return frame->f_code;
}

static PyFrameObject* PyFrame_GetBack(PyFrameObject *frame)
{
Py_XINCREF(frame->f_back);
return frame->f_back;
}
#endif

#if PY_VERSION_HEX < 0x030B00A7 && !defined(PYPY_VERSION)
static PyObject* PyFrame_GetLocals(PyFrameObject *frame)
{
if (PyFrame_FastToLocalsWithError(frame) < 0) {
return NULL;
}
Py_INCREF(frame->f_locals);
fowles marked this conversation as resolved.
Show resolved Hide resolved
return frame->f_locals;
}

static 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 +127,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