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: 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