python3-gevent: fix build for Python 3.11

This commit is contained in:
Đoàn Trần Công Danh 2022-10-03 23:05:11 +07:00 committed by Đoàn Trần Công Danh
parent a8004f0652
commit cc3d4c1dc5
2 changed files with 145 additions and 1 deletions

View File

@ -0,0 +1,144 @@
https://github.com/gevent/gevent/pull/1872.patch
From 90e9169c915a640739880b55ed95f88ce21fa7b0 Mon Sep 17 00:00:00 2001
From: Victor Stinner <vstinner@python.org>
Date: Tue, 1 Mar 2022 22:28:40 +0100
Subject: [PATCH] Add Python 3.11 alpha 6 support
* On Python 3.11a6 and newer, get the PyFrameObject structure from
the internal C API ("internal/pycore_frame.h").
* On Python 3.9 and newer, use PyFrame_GetBack() and
PyFrame_GetCode().
* Add frame getter and setter functions to greenlet:
* get_f_code(frame)
* set_f_lineno(frame, lineno)
* set_f_code(frame, code)
* greenlet.h: the CFrame type has been renamed to _PyCFrame.
---
_setuputils.py | 4 +++
deps/greenlet/greenlet.h | 6 +++-
src/gevent/_gevent_cgreenlet.pxd | 59 ++++++++++++++++++++++++--------
src/gevent/greenlet.py | 7 ++--
4 files changed, 59 insertions(+), 17 deletions(-)
diff --git a/_setuputils.py b/_setuputils.py
index 7257b3eea..0b14ab1f0 100644
--- a/_setuputils.py
+++ b/_setuputils.py
@@ -244,6 +244,10 @@ def cythonize1(ext):
'infer_types': True,
'nonecheck': False,
},
+ compile_time_env={
+ 'PY39B1': sys.hexversion >= 0x030900B1,
+ 'PY311A6': sys.hexversion >= 0x030B00A6,
+ },
# The common_utility_include_dir (not well documented)
# causes Cython to emit separate files for much of the
# static support code. Each of the modules then includes
diff --git a/src/gevent/_gevent_cgreenlet.pxd b/src/gevent/_gevent_cgreenlet.pxd
index cbb81a638..246773e24 100644
--- a/src/gevent/_gevent_cgreenlet.pxd
+++ b/src/gevent/_gevent_cgreenlet.pxd
@@ -57,30 +57,61 @@ cdef extern from "Python.h":
ctypedef class types.CodeType [object PyCodeObject]:
pass
-cdef extern from "frameobject.h":
-
- ctypedef class types.FrameType [object PyFrameObject]:
- cdef CodeType f_code
- # Accessing the f_lineno directly doesn't work. There is an accessor
- # function, PyFrame_GetLineNumber that is needed to turn the raw line number
- # into the executing line number.
- # cdef int f_lineno
- # We can't declare this in the object as an object, because it's
- # allowed to be NULL, and Cython can't handle that.
- # We have to go through the python machinery to get a
- # proper None instead, or use an inline function.
- cdef void* f_back
+IF PY311A6:
+ cdef extern from "internal/pycore_frame.h":
+ ctypedef class types._PyInterpreterFrame [object _PyInterpreterFrame]:
+ cdef CodeType f_code
+
+ ctypedef class types.FrameType [object PyFrameObject]:
+ cdef _PyInterpreterFrame f_frame
+ # Accessing the f_lineno directly doesn't work. There is an accessor
+ # function, PyFrame_GetLineNumber that is needed to turn the raw line number
+ # into the executing line number.
+ # cdef int f_lineno
+ # We can't declare this in the object as an object, because it's
+ # allowed to be NULL, and Cython can't handle that.
+ # We have to go through the python machinery to get a
+ # proper None instead, or use an inline function.
+ cdef void* f_back
+ELSE:
+ cdef extern from "frameobject.h":
+ ctypedef class types.FrameType [object PyFrameObject]:
+ cdef CodeType f_code
+ cdef void* f_back
+cdef extern from "frameobject.h":
int PyFrame_GetLineNumber(FrameType frame)
+ IF PY39B1:
+ CodeType PyFrame_GetCode(FrameType frame)
+ void* PyFrame_GetBack(FrameType frame)
@cython.nonecheck(False)
cdef inline FrameType get_f_back(FrameType frame):
+ IF PY39B1:
+ f_back = PyFrame_GetBack(frame)
+ ELSE:
+ f_back = frame.f_back
if frame.f_back != NULL:
- return <FrameType>frame.f_back
+ return <FrameType>f_back
cdef inline int get_f_lineno(FrameType frame):
return PyFrame_GetLineNumber(frame)
+cdef inline void set_f_lineno(FrameType frame, int lineno):
+ frame.f_lineno = lineno
+
+cdef inline CodeType get_f_code(FrameType frame):
+ IF PY39B1:
+ return PyFrame_GetCode(frame)
+ ELSE:
+ return frame.f_code
+
+cdef inline void set_f_code(FrameType frame, CodeType code):
+ IF PY311A6:
+ frame.f_frame.f_code = code
+ ELSE:
+ frame.f_code = code
+
cdef void _init()
cdef class SpawnedLink:
diff --git a/src/gevent/greenlet.py b/src/gevent/greenlet.py
index bed12ed44..f925770bb 100644
--- a/src/gevent/greenlet.py
+++ b/src/gevent/greenlet.py
@@ -58,6 +58,9 @@
# Frame access
locals()['get_f_back'] = lambda frame: frame.f_back
locals()['get_f_lineno'] = lambda frame: frame.f_lineno
+locals()['set_f_lineno'] = lambda frame, lineno: setattr(frame, 'f_lineno', lineno)
+locals()['get_f_code'] = lambda frame: frame.f_code
+locals()['set_f_code'] = lambda frame, code: setattr(frame, 'f_code', code)
if _PYPY:
import _continuation # pylint:disable=import-error
@@ -157,8 +160,8 @@ def _extract_stack(limit):
# Arguments are always passed to the constructor as Python objects,
# meaning we wind up boxing the f_lineno just to unbox it if we pass it.
# It's faster to simply assign once the object is created.
- older_Frame.f_code = frame.f_code
- older_Frame.f_lineno = get_f_lineno(frame) # pylint:disable=undefined-variable
+ set_f_code(older_Frame.f_code, get_f_code(frame))
+ set_f_lineno(older_Frame.f_lineno, get_f_lineno(frame)) # pylint:disable=undefined-variable
if newer_Frame is not None:
newer_Frame.f_back = older_Frame
newer_Frame = older_Frame

View File

@ -21,7 +21,7 @@ post_extract() {
}
do_check() {
PYTHONPATH="$(cd build/lib* && pwd)" python -m gevent.tests
PYTHONPATH="$(cd build/lib* && pwd)" python3 -m gevent.tests
}
post_install() {