forked from conda-forge/protobuf-feedstock
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #17 from AnacondaRecipes/3.20.1_py311
3.20.1 python 3.11 compatibility
- Loading branch information
Showing
2 changed files
with
137 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
Patch adapted from: https://github.com/protocolbuffers/protobuf/pull/10403 | ||
|
||
From da973aff2adab60a9e516d3202c111dbdde1a50f Mon Sep 17 00:00:00 2001 | ||
From: Alexander Shadchin <alexandr.shadchin@gmail.com> | ||
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. | ||
|
||
diff --git a/python/google/protobuf/pyext/descriptor.cc b/python/google/protobuf/pyext/descriptor.cc | ||
index 162531226..e93ec4809 100644 | ||
--- a/python/google/protobuf/pyext/descriptor.cc | ||
+++ b/python/google/protobuf/pyext/descriptor.cc | ||
@@ -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); | ||
+ 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 { | ||
@@ -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. |