commit:     35c5ad765e20f14e514f79b77d633a4c2e220d4d
Author:     Sam James <sam <AT> gentoo <DOT> org>
AuthorDate: Tue Oct 25 23:02:41 2022 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Tue Oct 25 23:02:47 2022 +0000
URL:        https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=35c5ad76

dev-python/protobuf-python: fix Python 3.11 build

Bug: https://bugs.gentoo.org/844184
Signed-off-by: Sam James <sam <AT> gentoo.org>

 .../files/protobuf-python-4.21.8-python311.patch   | 132 +++++++++++++++++++++
 .../protobuf-python/protobuf-python-4.21.8.ebuild  |   1 +
 2 files changed, 133 insertions(+)

diff --git 
a/dev-python/protobuf-python/files/protobuf-python-4.21.8-python311.patch 
b/dev-python/protobuf-python/files/protobuf-python-4.21.8-python311.patch
new file mode 100644
index 000000000000..b9aca40776c5
--- /dev/null
+++ b/dev-python/protobuf-python/files/protobuf-python-4.21.8-python311.patch
@@ -0,0 +1,132 @@
+https://github.com/protocolbuffers/protobuf/commit/2206b63c4649cf2e8a06b66c9191c8ef862ca519
+https://github.com/protocolbuffers/protobuf/pull/10403
+https://github.com/protocolbuffers/protobuf/issues/10305
+https://bugs.gentoo.org/844184
+
+From da973aff2adab60a9e516d3202c111dbdde1a50f Mon Sep 17 00:00:00 2001
+From: Alexander Shadchin <alexandr.shadc...@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.
+--- a/google/protobuf/pyext/descriptor.cc
++++ b/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.
+

diff --git a/dev-python/protobuf-python/protobuf-python-4.21.8.ebuild 
b/dev-python/protobuf-python/protobuf-python-4.21.8.ebuild
index 7d5ab4946eb9..572a571542c6 100644
--- a/dev-python/protobuf-python/protobuf-python-4.21.8.ebuild
+++ b/dev-python/protobuf-python/protobuf-python-4.21.8.ebuild
@@ -57,6 +57,7 @@ PARENT_PATCHES=(
 
 # Here for patches within "python/" subdirectory.
 PATCHES=(
+       "${FILESDIR}"/${P}-python311.patch
 )
 
 python_prepare_all() {

Reply via email to