From 1ccdfbe2a503da16ab638f8f7906d07da1304ac1 Mon Sep 17 00:00:00 2001 From: Chris Sewell Date: Mon, 8 Mar 2021 13:22:53 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20FIX:=20`Task.cancel`=20should=20?= =?UTF-8?q?not=20set=20state=20as=20EXCEPTED=20(#214)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `asyncio.CancelledError` are generated when an async task is cancelled. In python 3.7 it inherits from `Exception`, whereas in python 3.8+ it inherits from `BaseException`. This meant it python 3.7 it was being caught by the broad `except Exception`, and setting the process state to EXCEPTED, whereas in python 3.8+ it was being re-raised to the caller. We now ensure in both versions it is re-raised. --- plumpy/process_states.py | 6 ++++++ plumpy/processes.py | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/plumpy/process_states.py b/plumpy/process_states.py index 6bb3f85f..1ff201dc 100644 --- a/plumpy/process_states.py +++ b/plumpy/process_states.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +import asyncio from enum import Enum import sys import traceback @@ -232,6 +233,11 @@ async def execute(self) -> State: # type: ignore # pylint: disable=invalid-over except Interruption: # Let this bubble up to the caller raise + except asyncio.CancelledError: # pylint: disable=try-except-raise + # note this re-raise is only required in python<=3.7, + # for python>=3.8 asyncio.CancelledError does not inherit from Exception, + # so will not be caught below + raise except Exception: # pylint: disable=broad-except excepted = self.create_state(ProcessState.EXCEPTED, *sys.exc_info()[1:]) return cast(State, excepted) diff --git a/plumpy/processes.py b/plumpy/processes.py index 5dee8210..821d6bd1 100644 --- a/plumpy/processes.py +++ b/plumpy/processes.py @@ -1193,6 +1193,12 @@ async def step(self) -> None: except KeyboardInterrupt: # pylint: disable=try-except-raise raise + except asyncio.CancelledError: # pylint: disable=try-except-raise + # note this re-raise is only required in python<=3.7, + # where asyncio.CancelledError == concurrent.futures.CancelledError + # it is encountered when the run_task is cancelled + # for python>=3.8 asyncio.CancelledError does not inherit from Exception, so will not be caught below + raise except Exception: # pylint: disable=broad-except # Overwrite the next state to go to excepted directly next_state = self.create_state(process_states.ProcessState.EXCEPTED, *sys.exc_info()[1:])