diff --git a/snakemake/scheduler.py b/snakemake/scheduler.py index c26f39e9a..1b3ac8669 100644 --- a/snakemake/scheduler.py +++ b/snakemake/scheduler.py @@ -43,6 +43,11 @@ def cumsum(iterable, zero=[0]): "Exiting because a job execution failed. " "Look above for error message" ) +_ERROR_MSG_ISSUE_823 = ( + "BUG: Out of jobs ready to be started, but not all files built yet." + " Please check https://github.com/snakemake/snakemake/issues/823 for more information." +) + class DummyRateLimiter(ContextDecorator): def __enter__(self): @@ -470,11 +475,23 @@ def schedule(self): return False continue - # normal shutdown because all jobs have been finished + # all runnable jobs have finished, normal shutdown if not needrun and (not running or self.workflow.immediate_submit): self._executor.shutdown() if errors: logger.error(_ERROR_MSG_FINAL) + # we still have unfinished jobs. this is not good. direct + # user to github issue + if self.remaining_jobs: + logger.error(_ERROR_MSG_ISSUE_823) + logger.error( + "Remaining jobs:\n" + + "\n".join( + " - " + str(job) + ": " + ", ".join(job.output) + for job in self.remaining_jobs + ) + ) + return False return not errors # continue if no new job needs to be executed diff --git a/tests/test_issue823_3/Snakefile b/tests/test_issue823_3/Snakefile new file mode 100644 index 000000000..67f777b51 --- /dev/null +++ b/tests/test_issue823_3/Snakefile @@ -0,0 +1,9 @@ +rule all: + input: + "a.txt" + +checkpoint a: + output: + "a.txt" + shell: + "touch {output}" diff --git a/tests/test_issue823_3/expected-results/a.txt b/tests/test_issue823_3/expected-results/a.txt new file mode 100644 index 000000000..e69de29bb diff --git a/tests/tests.py b/tests/tests.py index bfa2503fa..547889599 100644 --- a/tests/tests.py +++ b/tests/tests.py @@ -887,6 +887,11 @@ def test_issue823_2(): run(dpath("test_issue823_2")) +@skip_on_windows +def test_issue823_3(): + run(dpath("test_issue823_3")) + + @skip_on_windows def test_pathlib(): run(dpath("test_pathlib"))