diff --git a/docs/changes.rst b/docs/changes.rst index 484c41d6..6eb70ea5 100644 --- a/docs/changes.rst +++ b/docs/changes.rst @@ -18,6 +18,8 @@ all releases are available on `PyPI `_ and - :gh:`118` makes the path to the configuration in the session header os-specific. - :gh:`119` changes that when marker or keyword expressions are used to select tasks, also the predecessors of the selected tasks will be executed. +- :gh:`120` implements that a single ``KeyboardInterrupt`` stops the execution and + previously collected reports are shown. 0.0.16 - 2021-06-25 diff --git a/src/_pytask/execute.py b/src/_pytask/execute.py index 929b9e59..31d44223 100644 --- a/src/_pytask/execute.py +++ b/src/_pytask/execute.py @@ -14,6 +14,7 @@ from _pytask.nodes import FilePathNode from _pytask.report import ExecutionReport from _pytask.shared import reduce_node_name +from _pytask.traceback import remove_traceback_from_exc_info from rich.traceback import Traceback @@ -67,6 +68,10 @@ def pytask_execute_task_protocol(session, task): session.hook.pytask_execute_task_setup(session=session, task=task) session.hook.pytask_execute_task(session=session, task=task) session.hook.pytask_execute_task_teardown(session=session, task=task) + except KeyboardInterrupt: + short_exc_info = remove_traceback_from_exc_info(sys.exc_info()) + report = ExecutionReport.from_task_and_exception(task, short_exc_info) + session.should_stop = True except Exception: report = ExecutionReport.from_task_and_exception(task, sys.exc_info()) else: diff --git a/src/_pytask/live.py b/src/_pytask/live.py index 3e20582c..eacad47f 100644 --- a/src/_pytask/live.py +++ b/src/_pytask/live.py @@ -167,5 +167,4 @@ def _generate_status(self): if self._n_errors > 0: msg += f" {self._n_errors} errors." status = Status(msg, spinner="dots") - status._name = "collection_status" return status diff --git a/src/_pytask/logging.py b/src/_pytask/logging.py index dcda9f60..2c794d2d 100644 --- a/src/_pytask/logging.py +++ b/src/_pytask/logging.py @@ -97,4 +97,6 @@ def _style_infos(infos: List[Tuple[Any]]) -> str: for value, description, color in infos: if value: message.append(f"[{color}]{value} {description}[/]") + if not message: + message = ["nothing to report"] return ", ".join(message)