From 4258ec67335d5d3e062508dfacc10d791662eda0 Mon Sep 17 00:00:00 2001 From: Michael Abbott Date: Fri, 29 Mar 2019 11:40:58 +0000 Subject: [PATCH 1/2] Fix cothread exception switching for Python 3.7 In Python 3.7 the thread exception state was moved. As cothread needs to do its own management of this state we have to track this change. There is also an extra complication: exc_info daisy-chaining. It's not clear how this should interact with cothread and whether this commit is correct. We'll need to add some extra exception tests to validate this. --- context/_coroutine.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/context/_coroutine.c b/context/_coroutine.c index d7f045b..550dd67 100644 --- a/context/_coroutine.c +++ b/context/_coroutine.c @@ -85,9 +85,15 @@ static void *coroutine_wrapper(void *action_, void *arg_) /* Also reset the exception state in case it's non NULL at this point. We * don't own these pointers at this point, coroutine_switch does. */ +#if PY_VERSION_HEX >= 0x03070000 + /* In Python 3.7 the exec info moved. */ + thread_state->exc_state = (_PyErr_StackItem) { }; + thread_state->exc_info = &thread_state->exc_state; +#else thread_state->exc_type = NULL; thread_state->exc_value = NULL; thread_state->exc_traceback = NULL; +#endif /* Call the given action with the passed argument. */ PyObject *action = *(PyObject **)action_; @@ -102,9 +108,15 @@ static void *coroutine_wrapper(void *action_, void *arg_) * All these pointers really are defunct, because as soon as we return * coroutine_switch will replace all these values. */ Py_XDECREF(thread_state->frame); +#if PY_VERSION_HEX >= 0x03070000 + Py_XDECREF(thread_state->exc_state.exc_type); + Py_XDECREF(thread_state->exc_state.exc_value); + Py_XDECREF(thread_state->exc_state.exc_traceback); +#else Py_XDECREF(thread_state->exc_type); Py_XDECREF(thread_state->exc_value); Py_XDECREF(thread_state->exc_traceback); +#endif return result; } @@ -148,9 +160,14 @@ static PyObject *coroutine_switch(PyObject *Self, PyObject *args) * this then we get confusion about the lifetime of exception state * between coroutines. The most obvious problem is that the exception * isn't properly cleared on function return. */ +#if PY_VERSION_HEX >= 0x03070000 + _PyErr_StackItem exc_state = thread_state->exc_state; + _PyErr_StackItem *exc_info = thread_state->exc_info; +#else PyObject *exc_type = thread_state->exc_type; PyObject *exc_value = thread_state->exc_value; PyObject *exc_traceback = thread_state->exc_traceback; +#endif /* Switch to new coroutine. For the duration arg needs an extra * reference count, it'll be accounted for either on the next returned @@ -165,9 +182,14 @@ static PyObject *coroutine_switch(PyObject *Self, PyObject *args) thread_state->recursion_depth = recursion_depth; /* Restore the exception state. */ +#if PY_VERSION_HEX >= 0x03070000 + thread_state->exc_state = exc_state; + thread_state->exc_info = exc_info; +#else thread_state->exc_type = exc_type; thread_state->exc_value = exc_value; thread_state->exc_traceback = exc_traceback; +#endif return result; } else From 9cfd384f50030f0e88d4739e54f0077432a221e0 Mon Sep 17 00:00:00 2001 From: Will Rogers Date: Wed, 3 Apr 2019 13:32:59 +0100 Subject: [PATCH 2/2] Add Python 3.7 to Travis configuration, and drop 3.3. Python 3.3 is not supported by the newer Travis builds on Ubuntu Xenial. --- .travis.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index d4fd971..f57f170 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,13 +1,12 @@ sudo: false +dist: xenial language: python python: - "2.7" - - "3.3" - "3.4" - "3.5" - "3.6" - - + - "3.7" # Get epics base addons: