diff --git a/protobuf-3.19.4-python3.11.patch b/protobuf-3.19.4-python3.11.patch new file mode 100644 index 0000000..3e2ee2e --- /dev/null +++ b/protobuf-3.19.4-python3.11.patch @@ -0,0 +1,135 @@ +From 5576f98f5d6aa0cc1e845a5fe5d00c034ef51f30 Mon Sep 17 00:00:00 2001 +From: Alexander Shadchin +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. +--- + python/google/protobuf/pyext/descriptor.cc | 75 ++++++++++++++++++---- + 1 file changed, 62 insertions(+), 13 deletions(-) + +diff --git a/python/google/protobuf/pyext/descriptor.cc b/python/google/protobuf/pyext/descriptor.cc +index a2993d908..44d811923 100644 +--- a/python/google/protobuf/pyext/descriptor.cc ++++ b/python/google/protobuf/pyext/descriptor.cc +@@ -57,6 +57,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 { +@@ -95,48 +126,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 == NULL) { +- 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 == NULL) { +- return false; ++ goto exit; + } + } + +- if (frame->f_code->co_filename == NULL) { +- return false; ++ frame_code = PyFrame_GetCode(frame); ++ if (frame_code->co_filename == NULL) { ++ 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. +-- +2.38.1 + diff --git a/protobuf.spec b/protobuf.spec index e6a630a..51026fc 100644 --- a/protobuf.spec +++ b/protobuf.spec @@ -1,12 +1,8 @@ # Build -python subpackage %bcond_without python -# Build -python subpackage with C++ -# Not compatible with Python 3.11 -%if 0%{?fedora} >= 37 -%bcond_with python_cpp -%else +# Build -python subpackage with C++. This significantly improves performance +# compared to the pure-Python implementation. %bcond_without python_cpp -%endif # Build -java subpackage %ifarch %{java_arches} %bcond_without java @@ -74,6 +70,11 @@ Patch2: disable-tests-on-32-bit-systems.patch # throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module @12d5624a # at com.google.protobuf.ServiceTest.testGetPrototype(ServiceTest.java:107) Patch3: protobuf-3.19.4-jre17-add-opens.patch +# Backport upstream commit da973aff2adab60a9e516d3202c111dbdde1a50f: +# Fix build with Python 3.11 +# +# The PyFrameObject structure members have been removed from the public C API. +Patch4: protobuf-3.19.4-python3.11.patch # A bundled copy of jsoncpp is included in the conformance tests, but the # result is not packaged, so we do not treat it as a formal bundled @@ -287,6 +288,7 @@ descriptions in the Emacs editor. %patch2 -p0 %endif %patch3 -p1 -b .jre17 +%patch4 -p1 -b .python311 # Copy in the needed gtest/gmock implementations. %setup -q -T -D -b 3 -n %{name}-%{version}%{?rcver} @@ -488,6 +490,7 @@ install -p -m 0644 %{SOURCE2} %{buildroot}%{_emacs_sitestartdir} - Drop obsolete python_provide macro - Drop python3_pkgversion macro - Update summary and description to refer to “Python” instead of “Python 3” +- Re-enable compiled Python extension on Python 3.11 * Sun Aug 14 2022 Orion Poplawski - 3.19.4-6 - Build python support with C++ (bz#2107921)