Merge pull request #10403 from shadchin/python311

Fix build with Python 3.11
pull/10541/head
Matt Fowles Kulukundis 2 years ago committed by GitHub
commit 2206b63c46
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 75
      python/google/protobuf/pyext/descriptor.cc

@ -58,6 +58,37 @@
: 0) \ : 0) \
: PyBytes_AsStringAndSize(ob, (charpp), (sizep))) : 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);
return frame->f_locals;
}
static PyObject* PyFrame_GetGlobals(PyFrameObject *frame)
{
Py_INCREF(frame->f_globals);
return frame->f_globals;
}
#endif
namespace google { namespace google {
namespace protobuf { namespace protobuf {
namespace python { namespace python {
@ -96,48 +127,66 @@ bool _CalledFromGeneratedFile(int stacklevel) {
// This check is not critical and is somewhat difficult to implement correctly // This check is not critical and is somewhat difficult to implement correctly
// in PyPy. // in PyPy.
PyFrameObject* frame = PyEval_GetFrame(); PyFrameObject* frame = PyEval_GetFrame();
PyCodeObject* frame_code = nullptr;
PyObject* frame_globals = nullptr;
PyObject* frame_locals = nullptr;
bool result = false;
if (frame == nullptr) { if (frame == nullptr) {
return false; goto exit;
} }
Py_INCREF(frame);
while (stacklevel-- > 0) { while (stacklevel-- > 0) {
frame = frame->f_back; PyFrameObject* next_frame = PyFrame_GetBack(frame);
Py_DECREF(frame);
frame = next_frame;
if (frame == nullptr) { if (frame == nullptr) {
return false; goto exit;
} }
} }
if (frame->f_code->co_filename == nullptr) { frame_code = PyFrame_GetCode(frame);
return false; if (frame_code->co_filename == nullptr) {
goto exit;
} }
char* filename; char* filename;
Py_ssize_t filename_size; 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, &filename_size) < 0) {
// filename is not a string. // filename is not a string.
PyErr_Clear(); PyErr_Clear();
return false; goto exit;
} }
if ((filename_size < 3) || if ((filename_size < 3) ||
(strcmp(&filename[filename_size - 3], ".py") != 0)) { (strcmp(&filename[filename_size - 3], ".py") != 0)) {
// Cython's stack does not have .py file name and is not at global module // Cython's stack does not have .py file name and is not at global module
// scope. // scope.
return true; result = true;
goto exit;
} }
if (filename_size < 7) { if (filename_size < 7) {
// filename is too short. // filename is too short.
return false; goto exit;
} }
if (strcmp(&filename[filename_size - 7], "_pb2.py") != 0) { if (strcmp(&filename[filename_size - 7], "_pb2.py") != 0) {
// Filename is not ending with _pb2. // 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 // Not at global module scope
return false; goto exit;
} }
#endif #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. // If the calling code is not a _pb2.py file, raise AttributeError.

Loading…
Cancel
Save