From 11123213188672a3b6e5acfffed18d9e0ccc8819 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20K=C3=B6ster?= Date: Fri, 1 Apr 2022 18:21:43 +0200 Subject: [PATCH] fix: proper error message if resource types do not match (#1556) --- snakemake/rules.py | 20 ++++++++++++----- tests/test_github_issue1389/Snakefile | 22 +++++++++++++++++++ .../expected-results/test1.txt | 0 .../expected-results/test2.txt | 0 tests/tests.py | 5 +++++ 5 files changed, 42 insertions(+), 5 deletions(-) create mode 100644 tests/test_github_issue1389/Snakefile create mode 100644 tests/test_github_issue1389/expected-results/test1.txt create mode 100644 tests/test_github_issue1389/expected-results/test2.txt diff --git a/snakemake/rules.py b/snakemake/rules.py index 5a13d8ff2..7e57d6778 100644 --- a/snakemake/rules.py +++ b/snakemake/rules.py @@ -1081,13 +1081,23 @@ def apply(name, res, threads=None): if not isinstance(res, int) and not isinstance(res, str): raise WorkflowError( - "Resources function did not return int, float (floats are " - "rouded to the nearest integer), or str.", + f"Resource {name} is neither int, float(would be rounded to nearest int), or str.", rule=self, ) - if isinstance(res, int): - global_res = self.workflow.global_resources.get(name, res) - if global_res is not None: + + global_res = self.workflow.global_resources.get(name) + if global_res is not None: + if not isinstance(res, TBDString) and type(res) != type(global_res): + global_type = ( + "an int" if isinstance(global_res, int) else type(global_res) + ) + raise WorkflowError( + f"Resource {name} is of type {type(res).__name__} but global resource constraint " + f"defines {global_type} with value {global_res}. " + "Resources with the same name need to have the same types (int, float, or str are allowed).", + rule=self, + ) + if isinstance(res, int): res = min(global_res, res) return res diff --git a/tests/test_github_issue1389/Snakefile b/tests/test_github_issue1389/Snakefile new file mode 100644 index 000000000..cd2f2bcc0 --- /dev/null +++ b/tests/test_github_issue1389/Snakefile @@ -0,0 +1,22 @@ +rule all: + input: + "test1.txt", + "test2.txt", + + +rule a: + output: + "test1.txt", + resources: + foo=1, + shell: + "touch {output}" + + +rule b: + output: + "test2.txt", + resources: + foo="bar", + shell: + "touch {output}" diff --git a/tests/test_github_issue1389/expected-results/test1.txt b/tests/test_github_issue1389/expected-results/test1.txt new file mode 100644 index 000000000..e69de29bb diff --git a/tests/test_github_issue1389/expected-results/test2.txt b/tests/test_github_issue1389/expected-results/test2.txt new file mode 100644 index 000000000..e69de29bb diff --git a/tests/tests.py b/tests/tests.py index 5d25e945b..edc285838 100644 --- a/tests/tests.py +++ b/tests/tests.py @@ -1609,3 +1609,8 @@ def test_github_issue1498(): def test_cleanup_metadata_fail(): run(dpath("test09"), cleanup_metadata=["xyz"]) + + +@skip_on_windows # same on win, no need to test +def test_github_issue1389(): + run(dpath("test_github_issue1389"), resources={"foo": 4}, shouldfail=True)