summaryrefslogtreecommitdiffstats
path: root/meta-python/recipes-devtools/python/python3-gevent/py-3.11.patch
blob: 6750c1a3cfd0084a0dbf2fa9a81414e108410725 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
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.

Upstream-Status: Submitted [https://github.com/gevent/gevent/pull/1872]
Signed-off-by: Alexander Kanavin <alex@linutronix.de>
---
 _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/deps/greenlet/greenlet.h b/deps/greenlet/greenlet.h
index 830bef8dd..f07ce1833 100644
--- a/deps/greenlet/greenlet.h
+++ b/deps/greenlet/greenlet.h
@@ -14,6 +14,10 @@ extern "C" {
 /* This is deprecated and undocumented. It does not change. */
 #define GREENLET_VERSION "1.0.0"
 
+#if PY_VERSION_HEX < 0x30B00A6
+#  define _PyCFrame CFrame
+#endif
+
 typedef struct _greenlet {
     PyObject_HEAD
     char* stack_start;
@@ -39,7 +43,7 @@ typedef struct _greenlet {
     PyObject* context;
 #endif
 #if PY_VERSION_HEX >= 0x30A00B1
-    CFrame* cframe;
+    _PyCFrame* cframe;
 #endif
 } PyGreenlet;
 
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