Add fix for Python 3.7

This commit is contained in:
Miro Hrončok 2018-07-03 18:49:22 +02:00
parent bbf9fcdc73
commit 64fd86d417
2 changed files with 190 additions and 1 deletions

183
132.patch Normal file
View File

@ -0,0 +1,183 @@
From 8d998cb79ebea348a8f5258b642a1f772ecd93b8 Mon Sep 17 00:00:00 2001
From: Victor Stinner <vstinner@redhat.com>
Date: Tue, 3 Jul 2018 16:01:37 +0200
Subject: [PATCH] Fix #131: Port to Py3.7: handle tstate->exc_info
Fix Python 3.7 support: handle also tstate->exc_info, not only
tstate->exc_state.
---
greenlet.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++--------------
greenlet.h | 9 +++++++++
2 files changed, 59 insertions(+), 14 deletions(-)
diff --git a/greenlet.c b/greenlet.c
index 0c85dd8..541efda 100644
--- a/greenlet.c
+++ b/greenlet.c
@@ -153,6 +153,21 @@ static PyObject* ts_empty_dict;
#define GREENLET_tp_is_gc 0
#endif /* !GREENLET_USE_GC */
+static void green_clear_exc(PyGreenlet *g)
+{
+#ifdef GREENLET_USE_EXC_INFO
+ g->exc_info = NULL;
+ g->exc_state.exc_type = NULL;
+ g->exc_state.exc_value = NULL;
+ g->exc_state.exc_traceback = NULL;
+ g->exc_state.previous_item = NULL;
+#else
+ g->exc_type = NULL;
+ g->exc_value = NULL;
+ g->exc_traceback = NULL;
+#endif
+}
+
static PyGreenlet* green_create_main(void)
{
PyGreenlet* gmain;
@@ -460,10 +475,9 @@ static int g_switchstack(void)
PyThreadState* tstate = PyThreadState_GET();
current->recursion_depth = tstate->recursion_depth;
current->top_frame = tstate->frame;
-#if PY_VERSION_HEX >= 0x030700A3
- current->exc_type = tstate->exc_state.exc_type;
- current->exc_value = tstate->exc_state.exc_value;
- current->exc_traceback = tstate->exc_state.exc_traceback;
+#ifdef GREENLET_USE_EXC_INFO
+ current->exc_info = tstate->exc_info;
+ current->exc_state = tstate->exc_state;
#else
current->exc_type = tstate->exc_type;
current->exc_value = tstate->exc_value;
@@ -474,9 +488,13 @@ static int g_switchstack(void)
if (err < 0) { /* error */
PyGreenlet* current = ts_current;
current->top_frame = NULL;
+#ifdef GREENLET_USE_EXC_INFO
+ green_clear_exc(current);
+#else
current->exc_type = NULL;
current->exc_value = NULL;
current->exc_traceback = NULL;
+#endif
assert(ts_origin == NULL);
ts_target = NULL;
@@ -488,18 +506,20 @@ static int g_switchstack(void)
tstate->recursion_depth = target->recursion_depth;
tstate->frame = target->top_frame;
target->top_frame = NULL;
-#if PY_VERSION_HEX >= 0x030700A3
- tstate->exc_state.exc_type = target->exc_type;
- tstate->exc_state.exc_value = target->exc_value;
- tstate->exc_state.exc_traceback = target->exc_traceback;
+#ifdef GREENLET_USE_EXC_INFO
+ tstate->exc_state = target->exc_state;
+ if (target->exc_info != NULL) {
+ tstate->exc_info = target->exc_info;
+ }
+ else {
+ tstate->exc_info = &tstate->exc_state;
+ }
#else
tstate->exc_type = target->exc_type;
tstate->exc_value = target->exc_value;
tstate->exc_traceback = target->exc_traceback;
#endif
- target->exc_type = NULL;
- target->exc_value = NULL;
- target->exc_traceback = NULL;
+ green_clear_exc(target);
assert(ts_origin == NULL);
Py_INCREF(target);
@@ -752,9 +772,7 @@ static int GREENLET_NOINLINE(g_initialstub)(void* mark)
self->stack_prev = ts_current;
}
self->top_frame = NULL;
- self->exc_type = NULL;
- self->exc_value = NULL;
- self->exc_traceback = NULL;
+ green_clear_exc(self);
self->recursion_depth = PyThreadState_GET()->recursion_depth;
/* restore arguments in case they are clobbered */
@@ -935,9 +953,15 @@ green_traverse(PyGreenlet *self, visitproc visit, void *arg)
- frames are not visited: alive greenlets are not garbage collected anyway */
Py_VISIT((PyObject*)self->parent);
Py_VISIT(self->run_info);
+#ifdef GREENLET_USE_EXC_INFO
+ Py_VISIT(self->exc_state.exc_type);
+ Py_VISIT(self->exc_state.exc_value);
+ Py_VISIT(self->exc_state.exc_traceback);
+#else
Py_VISIT(self->exc_type);
Py_VISIT(self->exc_value);
Py_VISIT(self->exc_traceback);
+#endif
Py_VISIT(self->dict);
return 0;
}
@@ -961,9 +985,15 @@ static int green_clear(PyGreenlet* self)
so even if it switches we are relatively safe. */
Py_CLEAR(self->parent);
Py_CLEAR(self->run_info);
+#ifdef GREENLET_USE_EXC_INFO
+ Py_CLEAR(self->exc_state.exc_type);
+ Py_CLEAR(self->exc_state.exc_value);
+ Py_CLEAR(self->exc_state.exc_traceback);
+#else
Py_CLEAR(self->exc_type);
Py_CLEAR(self->exc_value);
Py_CLEAR(self->exc_traceback);
+#endif
Py_CLEAR(self->dict);
return 0;
}
@@ -1030,9 +1060,15 @@ static void green_dealloc(PyGreenlet* self)
PyObject_ClearWeakRefs((PyObject *) self);
Py_CLEAR(self->parent);
Py_CLEAR(self->run_info);
+#ifdef GREENLET_USE_EXC_INFO
+ Py_CLEAR(self->exc_state.exc_type);
+ Py_CLEAR(self->exc_state.exc_value);
+ Py_CLEAR(self->exc_state.exc_traceback);
+#else
Py_CLEAR(self->exc_type);
Py_CLEAR(self->exc_value);
Py_CLEAR(self->exc_traceback);
+#endif
Py_CLEAR(self->dict);
Py_TYPE(self)->tp_free((PyObject*) self);
}
diff --git a/greenlet.h b/greenlet.h
index 6c9b8ee..995f500 100644
--- a/greenlet.h
+++ b/greenlet.h
@@ -13,6 +13,10 @@ extern "C" {
#define GREENLET_VERSION "0.4.13"
+#if PY_VERSION_HEX >= 0x030700A3
+# define GREENLET_USE_EXC_INFO
+#endif
+
typedef struct _greenlet {
PyObject_HEAD
char* stack_start;
@@ -25,9 +29,14 @@ typedef struct _greenlet {
struct _frame* top_frame;
int recursion_depth;
PyObject* weakreflist;
+#ifdef GREENLET_USE_EXC_INFO
+ _PyErr_StackItem *exc_info;
+ _PyErr_StackItem exc_state;
+#else
PyObject* exc_type;
PyObject* exc_value;
PyObject* exc_traceback;
+#endif
PyObject* dict;
} PyGreenlet;

View File

@ -2,7 +2,7 @@
Name: python-%{modname}
Version: 0.4.13
Release: 3%{?dist}
Release: 4%{?dist}
Summary: Lightweight in-process concurrent programming
License: MIT
URL: https://github.com/python-greenlet/greenlet
@ -10,6 +10,9 @@ Source0: %{url}/archive/%{version}/%{modname}-%{version}.tar.gz
# https://github.com/python-greenlet/greenlet/pull/120
Patch0001: 0001-Don-t-clobber-r2-register-on-ppc64el.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=1594248
Patch0002: https://github.com/python-greenlet/greenlet/pull/132.patch
%global _description \
The greenlet package is a spin-off of Stackless, a version of CPython\
that supports micro-threads called "tasklets". Tasklets run\
@ -92,6 +95,9 @@ Python 3 version.
%{_includedir}/python%{python3_version}*/%{modname}/
%changelog
* Tue Jul 03 2018 Miro Hrončok <mhroncok@redhat.com> - 0.4.13-4
- Add fix for Python 3.7
* Sat Jun 16 2018 Miro Hrončok <mhroncok@redhat.com> - 0.4.13-3
- Rebuilt for Python 3.7