mirror of
https://github.com/gentoo-mirror/gentoo.git
synced 2026-09-23 16:49:10 -07:00
dev-python/greenlet: enable py3.11
Signed-off-by: Arthur Zamarin <arthurzam@gentoo.org>
This commit is contained in:
223
dev-python/greenlet/files/greenlet-1.1.2-fix-py3.11.patch
Normal file
223
dev-python/greenlet/files/greenlet-1.1.2-fix-py3.11.patch
Normal file
@@ -0,0 +1,223 @@
|
||||
From: Victor Stinner <vstinner@python.org>
|
||||
Subject: [PATCH] Closes #305: Add Python 3.11 support
|
||||
|
||||
* Add GREENLET_PY311 macro
|
||||
* PyGreenlet structure:
|
||||
|
||||
* Add 3 members for the "data stack": 'datastack_chunk',
|
||||
'datastack_top' and 'datastack_limit'.
|
||||
* Add 'current_frame' member.
|
||||
|
||||
* Rename CFrame to _PyCFrame
|
||||
* tox.ini: Add py311 environment.
|
||||
|
||||
Changes partially backport from the master branch:
|
||||
commit 63e1099acc3677e614532bea0fa2e1967b69125f.
|
||||
|
||||
Co-Authored-By: Miro Hrončok <miro@hroncok.cz>
|
||||
|
||||
https://github.com/python-greenlet/greenlet/pull/306
|
||||
--- a/src/greenlet/greenlet.c
|
||||
+++ b/src/greenlet/greenlet.c
|
||||
@@ -170,9 +170,11 @@ green_clear_exc(PyGreenlet* g)
|
||||
{
|
||||
#if GREENLET_PY37
|
||||
g->exc_info = NULL;
|
||||
- g->exc_state.exc_type = NULL;
|
||||
g->exc_state.exc_value = NULL;
|
||||
+#if !GREENLET_PY311
|
||||
+ g->exc_state.exc_type = NULL;
|
||||
g->exc_state.exc_traceback = NULL;
|
||||
+#endif
|
||||
g->exc_state.previous_item = NULL;
|
||||
#else
|
||||
g->exc_type = NULL;
|
||||
@@ -525,8 +527,13 @@ g_switchstack(void)
|
||||
{ /* save state */
|
||||
PyGreenlet* current = ts_current;
|
||||
PyThreadState* tstate = PyThreadState_GET();
|
||||
+#if GREENLET_PY311
|
||||
+ current->recursion_depth = (tstate->recursion_limit
|
||||
+ - tstate->recursion_remaining);
|
||||
+#else
|
||||
current->recursion_depth = tstate->recursion_depth;
|
||||
current->top_frame = tstate->frame;
|
||||
+#endif
|
||||
#if GREENLET_PY37
|
||||
current->context = tstate->context;
|
||||
#endif
|
||||
@@ -551,6 +558,15 @@ g_switchstack(void)
|
||||
*/
|
||||
current->cframe = tstate->cframe;
|
||||
ts__g_switchstack_use_tracing = tstate->cframe->use_tracing;
|
||||
+#if GREENLET_PY311
|
||||
+ current->current_frame = tstate->cframe->current_frame;
|
||||
+ current->datastack_chunk = tstate->datastack_chunk;
|
||||
+ current->datastack_top = tstate->datastack_top;
|
||||
+ current->datastack_limit = tstate->datastack_limit;
|
||||
+ PyFrameObject *frame = PyThreadState_GetFrame(tstate);
|
||||
+ Py_XDECREF(frame); /* PyThreadState_GetFrame gives us a new reference. */
|
||||
+ current->top_frame = frame;
|
||||
+#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -574,9 +590,6 @@ g_switchstack(void)
|
||||
PyGreenlet* target = ts_target;
|
||||
PyGreenlet* origin = ts_current;
|
||||
PyThreadState* tstate = PyThreadState_GET();
|
||||
- tstate->recursion_depth = target->recursion_depth;
|
||||
- tstate->frame = target->top_frame;
|
||||
- target->top_frame = NULL;
|
||||
|
||||
#if GREENLET_PY37
|
||||
tstate->context = target->context;
|
||||
@@ -607,7 +620,18 @@ g_switchstack(void)
|
||||
*/
|
||||
tstate->cframe->use_tracing = ts__g_switchstack_use_tracing;
|
||||
#endif
|
||||
-
|
||||
+#if GREENLET_PY311
|
||||
+ tstate->recursion_remaining = (tstate->recursion_limit
|
||||
+ - target->recursion_depth);
|
||||
+ tstate->cframe->current_frame = target->current_frame;
|
||||
+ tstate->datastack_chunk = target->datastack_chunk;
|
||||
+ tstate->datastack_top = target->datastack_top;
|
||||
+ tstate->datastack_limit = target->datastack_limit;
|
||||
+#else
|
||||
+ tstate->recursion_depth = target->recursion_depth;
|
||||
+ tstate->frame = target->top_frame;
|
||||
+#endif
|
||||
+ target->top_frame = NULL;
|
||||
assert(ts_origin == NULL);
|
||||
Py_INCREF(target);
|
||||
ts_current = target;
|
||||
@@ -810,7 +834,7 @@ static int GREENLET_NOINLINE(g_initialstub)(void* mark)
|
||||
We want to defer copying the state info until we're sure
|
||||
we need it and are in a stable place to do so.
|
||||
*/
|
||||
- CFrame trace_info;
|
||||
+ _PyCFrame trace_info;
|
||||
#endif
|
||||
/* save exception in case getattr clears it */
|
||||
PyErr_Fetch(&exc, &val, &tb);
|
||||
@@ -875,7 +899,12 @@ static int GREENLET_NOINLINE(g_initialstub)(void* mark)
|
||||
}
|
||||
self->top_frame = NULL;
|
||||
green_clear_exc(self);
|
||||
+#if GREENLET_PY311
|
||||
+ self->recursion_depth = (PyThreadState_GET()->recursion_limit
|
||||
+ - PyThreadState_GET()->recursion_remaining);
|
||||
+#else
|
||||
self->recursion_depth = PyThreadState_GET()->recursion_depth;
|
||||
+#endif
|
||||
|
||||
/* restore arguments in case they are clobbered */
|
||||
ts_target = self;
|
||||
@@ -1006,13 +1035,13 @@ green_new(PyTypeObject* type, PyObject* args, PyObject* kwds)
|
||||
it uses the ``root_cframe`` just to have something to put there.
|
||||
However, once the greenlet is actually switched to for the first
|
||||
time, ``g_initialstub`` (which doesn't actually "return" while the
|
||||
- greenlet is running) stores a new CFrame on its local stack, and
|
||||
+ greenlet is running) stores a new _PyCFrame on its local stack, and
|
||||
copies the appropriate values from the currently running CFrame;
|
||||
- this is then made the CFrame for the newly-minted greenlet.
|
||||
+ this is then made the _PyCFrame for the newly-minted greenlet.
|
||||
``g_initialstub`` then proceeds to call ``glet.run()``, which
|
||||
- results in ``PyEval_...`` adding the CFrame to the list. Switches
|
||||
+ results in ``PyEval_...`` adding the _PyCFrame to the list. Switches
|
||||
continue as normal. Finally, when the greenlet finishes, the call to
|
||||
- ``glet.run()`` returns and the CFrame is taken out of the linked
|
||||
+ ``glet.run()`` returns and the _PyCFrame is taken out of the linked
|
||||
list and the stack value is now unused and free to expire.
|
||||
*/
|
||||
((PyGreenlet*)o)->cframe = &PyThreadState_GET()->root_cframe;
|
||||
@@ -1121,9 +1150,11 @@ green_traverse(PyGreenlet* self, visitproc visit, void* arg)
|
||||
Py_VISIT(self->context);
|
||||
#endif
|
||||
#if GREENLET_PY37
|
||||
- Py_VISIT(self->exc_state.exc_type);
|
||||
Py_VISIT(self->exc_state.exc_value);
|
||||
+#if !GREENLET_PY311
|
||||
+ Py_VISIT(self->exc_state.exc_type);
|
||||
Py_VISIT(self->exc_state.exc_traceback);
|
||||
+#endif
|
||||
#else
|
||||
Py_VISIT(self->exc_type);
|
||||
Py_VISIT(self->exc_value);
|
||||
@@ -1159,9 +1190,11 @@ green_clear(PyGreenlet* self)
|
||||
Py_CLEAR(self->context);
|
||||
#endif
|
||||
#if GREENLET_PY37
|
||||
- Py_CLEAR(self->exc_state.exc_type);
|
||||
Py_CLEAR(self->exc_state.exc_value);
|
||||
+#if !GREENLET_PY311
|
||||
+ Py_CLEAR(self->exc_state.exc_type);
|
||||
Py_CLEAR(self->exc_state.exc_traceback);
|
||||
+#endif
|
||||
#else
|
||||
Py_CLEAR(self->exc_type);
|
||||
Py_CLEAR(self->exc_value);
|
||||
@@ -1253,9 +1286,11 @@ green_dealloc(PyGreenlet* self)
|
||||
Py_CLEAR(self->context);
|
||||
#endif
|
||||
#if GREENLET_PY37
|
||||
- Py_CLEAR(self->exc_state.exc_type);
|
||||
Py_CLEAR(self->exc_state.exc_value);
|
||||
+#if !GREENLET_PY311
|
||||
+ Py_CLEAR(self->exc_state.exc_type);
|
||||
Py_CLEAR(self->exc_state.exc_traceback);
|
||||
+#endif
|
||||
#else
|
||||
Py_CLEAR(self->exc_type);
|
||||
Py_CLEAR(self->exc_value);
|
||||
--- a/src/greenlet/greenlet.h
|
||||
+++ b/src/greenlet/greenlet.h
|
||||
@@ -14,6 +14,15 @@ extern "C" {
|
||||
/* This is deprecated and undocumented. It does not change. */
|
||||
#define GREENLET_VERSION "1.0.0"
|
||||
|
||||
+#if PY_VERSION_HEX >= 0x30B00A6
|
||||
+# define GREENLET_PY311 1
|
||||
+ /* _PyInterpreterFrame moved to the internal C API in Python 3.11 */
|
||||
+# include <internal/pycore_frame.h>
|
||||
+#else
|
||||
+# define GREENLET_PY311 0
|
||||
+# define _PyCFrame CFrame
|
||||
+#endif
|
||||
+
|
||||
typedef struct _greenlet {
|
||||
PyObject_HEAD
|
||||
char* stack_start;
|
||||
@@ -25,6 +34,12 @@ typedef struct _greenlet {
|
||||
PyObject* run_info;
|
||||
struct _frame* top_frame;
|
||||
int recursion_depth;
|
||||
+#if GREENLET_PY311
|
||||
+ _PyInterpreterFrame *current_frame;
|
||||
+ _PyStackChunk *datastack_chunk;
|
||||
+ PyObject **datastack_top;
|
||||
+ PyObject **datastack_limit;
|
||||
+#endif
|
||||
PyObject* weakreflist;
|
||||
#if PY_VERSION_HEX >= 0x030700A3
|
||||
_PyErr_StackItem* exc_info;
|
||||
@@ -39,7 +54,7 @@ typedef struct _greenlet {
|
||||
PyObject* context;
|
||||
#endif
|
||||
#if PY_VERSION_HEX >= 0x30A00B1
|
||||
- CFrame* cframe;
|
||||
+ _PyCFrame* cframe;
|
||||
#endif
|
||||
} PyGreenlet;
|
||||
|
||||
--- a/tox.ini
|
||||
+++ b/tox.ini
|
||||
@@ -1,6 +1,6 @@
|
||||
[tox]
|
||||
envlist =
|
||||
- py27,py35,py36,py37,py38,py39,py310,docs
|
||||
+ py27,py35,py36,py37,py38,py39,py310,py311,docs
|
||||
|
||||
[testenv]
|
||||
commands =
|
||||
@@ -5,7 +5,7 @@ EAPI=8
|
||||
|
||||
DISTUTILS_USE_PEP517=setuptools
|
||||
# Note: greenlet is built-in in pypy
|
||||
PYTHON_COMPAT=( python3_{8..10} )
|
||||
PYTHON_COMPAT=( python3_{8..11} )
|
||||
|
||||
inherit distutils-r1
|
||||
|
||||
@@ -21,6 +21,10 @@ LICENSE="MIT"
|
||||
SLOT="0"
|
||||
KEYWORDS="~alpha amd64 arm arm64 -hppa -ia64 ~m68k ~mips ppc ppc64 ~riscv ~s390 sparc x86 ~amd64-linux ~x86-linux ~x64-macos"
|
||||
|
||||
PATCHES=(
|
||||
"${FILESDIR}/${P}-fix-py3.11.patch"
|
||||
)
|
||||
|
||||
distutils_enable_sphinx docs
|
||||
distutils_enable_tests unittest
|
||||
|
||||
|
||||
Reference in New Issue
Block a user