Skip to content

Commit 83a322e

Browse files
committed
[WDL 1.2] add task/workflow hints to grammar (only)
1 parent eab5b73 commit 83a322e

File tree

5 files changed

+141
-6
lines changed

5 files changed

+141
-6
lines changed

WDL/_grammar.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
)
1111
keywords["1.0"] = keywords["draft-2"] | set(["alias", "struct"])
1212
keywords["1.1"] = keywords["1.0"]
13-
keywords["1.2"] = keywords["1.1"] | set(["Directory", "env", "requirements"])
13+
keywords["1.2"] = keywords["1.1"] | set(["Directory", "env", "hints", "requirements"])
1414
keywords["development"] = keywords["1.2"]
1515

1616
# Grammar versions and their definitions. The productions for WDL 1.2 and development will be
@@ -40,7 +40,7 @@
4040
///////////////////////////////////////////////////////////////////////////////////////////////////
4141
4242
workflow: "workflow" CNAME "{" workflow_element* "}"
43-
?workflow_element: input_decls | any_decl | call | scatter | conditional | workflow_outputs | meta_section
43+
?workflow_element: input_decls | any_decl | call | scatter | conditional | workflow_outputs | meta_section | hints_section
4444
4545
scatter: "scatter" "(" CNAME "in" expr ")" "{" inner_workflow_element* "}"
4646
conditional: "if" "(" expr ")" "{" inner_workflow_element* "}"
@@ -65,6 +65,7 @@
6565
| output_decls
6666
| meta_section
6767
| requirements_section
68+
| hints_section
6869
| task_env_decl -> noninput_decl
6970
7071
tasks: task*
@@ -90,6 +91,14 @@
9091
requirements_section: ("requirements" | "runtime") "{" [runtime_kv (","? runtime_kv)*] "}"
9192
runtime_kv: CNAME ":" expr
9293
94+
// hints section
95+
hints_section: hints_object
96+
hints_object: "hints" "{" [hint_kv (","? hint_kv)*] ","? "}"
97+
hint_kv: CNAME ":" hint_value
98+
?hint_value: expr | hints_object | io_hint
99+
io_hint: ("input" | "output") "{" [io_hint_kv ("," io_hint_kv)*] ","? "}"
100+
io_hint_kv: CNAME ("." CNAME)* ":" hint_value
101+
93102
///////////////////////////////////////////////////////////////////////////////////////////////////
94103
// decl
95104
///////////////////////////////////////////////////////////////////////////////////////////////////

WDL/_parser.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,9 @@ def requirements_section(self, meta, items):
407407
d[k] = v
408408
return {"runtime": d}
409409

410+
def hints_section(self, meta, items):
411+
return {"hints": items[0]}
412+
410413
def task(self, meta, items):
411414
d = {"noninput_decls": []}
412415
for item in items:
@@ -427,6 +430,7 @@ def task(self, meta, items):
427430
assert "name" not in d
428431
d["name"] = item.value
429432
self._check_keyword(self._sp(meta), d["name"])
433+
# TODO: discarding d["hints"] for now (AST repr to be designed)
430434
return Tree.Task(
431435
self._sp(meta),
432436
d["name"],
@@ -532,6 +536,7 @@ def workflow(self, meta, items):
532536
output_idents_pos = None
533537
parameter_meta = None
534538
meta_section = None
539+
hints_section = None
535540
for item in items[1:]:
536541
if isinstance(item, dict):
537542
if "inputs" in item:
@@ -562,13 +567,20 @@ def workflow(self, meta, items):
562567
self._sp(meta), "redundant workflow parameter_meta sections"
563568
)
564569
parameter_meta = item["parameter_meta"]
570+
elif "hints" in item:
571+
if hints_section is not None:
572+
raise Error.MultipleDefinitions(
573+
self._sp(meta), "redundant workflow hints sections"
574+
)
575+
hints_section = item["hints"]
565576
else:
566577
assert False
567578
elif isinstance(item, (Tree.Call, Tree.Conditional, Tree.Decl, Tree.Scatter)):
568579
elements.append(item)
569580
else:
570581
assert False
571582
self._check_keyword(self._sp(meta), items[0].value)
583+
# TODO: discarding hints_section for now (AST repr to be designed)
572584
return Tree.Workflow(
573585
self._sp(meta),
574586
items[0].value,

tests/spec_tests/config.yaml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,18 +34,14 @@ wdl-1.2:
3434
- relative_and_absolute_task.wdl # issue #214
3535
- test_struct.wdl # issue #728
3636
# To be implemented:
37-
- allow_nested.wdl
3837
- chunk_array.wdl
3938
- file_sizes_task.wdl
4039
- multi_nested_inputs.wdl
41-
- input_hint_task.wdl
4240
- join_paths_task.wdl
4341
- one_mount_point_task.wdl
4442
- string_to_file.wdl
45-
- test_allow_nested_inputs.wdl
4643
- test_contains.wdl
4744
- test_find_task.wdl
48-
- test_hints_task.wdl
4945
- test_keys.wdl
5046
- test_matches_task.wdl
5147
- test_runtime_info_task.wdl
@@ -63,7 +59,9 @@ wdl-1.2:
6359
- serde_pair.wdl # expected output is wrong
6460
- single_return_code_task.wdl # issue #729
6561
- struct_to_struct.wdl # typo capitalized Struct
62+
- test_allow_nested_inputs.wdl # two definitions of `greeting` in `task nested`
6663
- test_contains_key.wdl # uses python-style `a if c else b` instead of `if c then a else b
64+
- test_hints_task.wdl # expected output is wrong (greetings.txt has no trailing newline, so wc -l returns 2 not 3)
6765
- test_length.wdl # typo in map literal
6866
- test_sub.wdl # issue #709
6967
- test_values.wdl # str_to_files should be str_to_ints

tests/test_1doc.py

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -551,6 +551,68 @@ def md5sum(filename, blocksize=65536):
551551
self.assertFalse(task.command.parts[0].strip().startswith("<<<"))
552552
self.assertFalse(task.command.parts[-1].strip().endswith(">>>"))
553553

554+
def test_hints(self):
555+
txt = """
556+
task t {
557+
input {
558+
Array[File] files
559+
}
560+
command <<<
561+
set -euxo pipefail
562+
mkdir files_out
563+
find _miniwdl_inputs -type f -print0 | xargs -0 -iXXX cp XXX files_out/
564+
>>>
565+
output {
566+
Array[File] files_out = glob("files_out/*")
567+
}
568+
runtime {
569+
container: ["ubuntu:20.04"]
570+
}
571+
hints {
572+
short_task: true
573+
inputs: input {
574+
files: hints {
575+
localization_optional: true
576+
}
577+
}
578+
}
579+
}
580+
"""
581+
task = WDL.parse_tasks(txt, version="1.2")[0]
582+
# TODO: test AST repr when implemented
583+
584+
txt = """
585+
task t {
586+
input {
587+
Array[File] files
588+
}
589+
command <<<
590+
set -euxo pipefail
591+
mkdir files_out
592+
find _miniwdl_inputs -type f -print0 | xargs -0 -iXXX cp XXX files_out/
593+
>>>
594+
output {
595+
Array[File] files_out = glob("files_out/*")
596+
}
597+
runtime {
598+
container: ["ubuntu:20.04"]
599+
}
600+
hints {
601+
short_task: true
602+
inputs: input {
603+
files: hints {
604+
localization_optional: true
605+
}
606+
}
607+
}
608+
hints {
609+
bogus: true
610+
}
611+
}
612+
"""
613+
with self.assertRaises(WDL.Error.MultipleDefinitions):
614+
WDL.parse_tasks(txt, version="1.2")[0].typecheck()
615+
554616

555617
class TestTypes(unittest.TestCase):
556618
def test_parser(self):
@@ -2515,6 +2577,49 @@ def test_keywords(self):
25152577
self.assertIsInstance(err.pos.line, int)
25162578
self.assertIsInstance(err.pos.column, int)
25172579

2580+
def test_workflow_hints(self):
2581+
doc = r"""version 1.2
2582+
workflow w {
2583+
input {
2584+
Array[String] names
2585+
}
2586+
scatter (name in names) {
2587+
String greeting = "Hello, " + name + "!"
2588+
}
2589+
output {
2590+
Array[String] greetings = greeting
2591+
}
2592+
hints {
2593+
allow_nested_inputs: true
2594+
}
2595+
}
2596+
"""
2597+
doc = WDL.parse_document(doc)
2598+
doc.typecheck()
2599+
# TODO: check hints AST once implemented
2600+
2601+
doc = r"""version 1.2
2602+
workflow w {
2603+
input {
2604+
Array[String] names
2605+
}
2606+
scatter (name in names) {
2607+
String greeting = "Hello, " + name + "!"
2608+
}
2609+
output {
2610+
Array[String] greetings = greeting
2611+
}
2612+
hints {
2613+
allow_nested_inputs: true
2614+
}
2615+
hints {
2616+
bogus: true
2617+
}
2618+
}
2619+
"""
2620+
with self.assertRaises(WDL.Error.MultipleDefinitions):
2621+
WDL.parse_document(doc)
2622+
25182623
class TestNoneLiteral(unittest.TestCase):
25192624
def test_none_expr(self):
25202625
doc = r"""

tests/test_7runner.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -882,6 +882,9 @@ def test_weird_filenames(self):
882882
output {
883883
Array[File] files_out = t.files_out
884884
}
885+
hints {
886+
allow_nested_inputs: true
887+
}
885888
}
886889
887890
task t {
@@ -899,6 +902,14 @@ def test_weird_filenames(self):
899902
runtime {
900903
container: ["ubuntu:20.04"]
901904
}
905+
hints {
906+
short_task: true
907+
inputs: input {
908+
files: hints {
909+
localization_optional: true
910+
}
911+
}
912+
}
902913
}
903914
"""
904915

0 commit comments

Comments
 (0)