Skip to content

Commit

Permalink
ensure optional fields in structs from input JSON
Browse files Browse the repository at this point in the history
Populate optional fields with None values when the input JSON omits them. This was done for `read_json()`, but not the case where the struct is read from a runner input JSON file.

#686
  • Loading branch information
mlin committed May 1, 2024
1 parent 6dfe837 commit 6b6d906
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 5 deletions.
8 changes: 8 additions & 0 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ jobs:
# - skylab_bulk_rna
runs-on: ubuntu-20.04
steps:
- name: Maximize build space
uses: AdityaGarg8/remove-unwanted-software@v3
with:
remove-dotnet: 'true'
remove-android: 'true'
remove-haskell: 'true'
remove-codeql: 'true'
if: ${{ matrix.ci_target == 'viral_assemble' }}
- name: Login to GitHub Packages Docker Registry
uses: docker/login-action@v1
with:
Expand Down
3 changes: 2 additions & 1 deletion WDL/Expr.py
Original file line number Diff line number Diff line change
Expand Up @@ -942,7 +942,8 @@ class Get(Base):

def __init__(self, pos: SourcePosition, expr: Base, member: Optional[str]) -> None:
super().__init__(pos)
assert expr
assert isinstance(expr, Base)
assert isinstance(member, (str, type(None)))
self.expr = expr
self.member = member

Expand Down
3 changes: 2 additions & 1 deletion WDL/Value.py
Original file line number Diff line number Diff line change
Expand Up @@ -579,7 +579,8 @@ def from_json(type: Type.Base, value: Any) -> Base:
raise Error.InputError(
f"couldn't initialize struct {str(type)} {type.members[k]} {k} from {json.dumps(v)}"
) from None
return Struct(Type.Object(type.members), items, extra=extra)
# Struct.__init__ will populate null for any omitted optional members
return Struct(type, items, extra=extra)
if type.optional and value is None:
return Null()
raise Error.InputError(f"couldn't construct {str(type)} from {json.dumps(value)}")
Expand Down
6 changes: 4 additions & 2 deletions WDL/_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -257,8 +257,10 @@ def left_name(self, meta, items) -> Expr.Base:
return Expr.Get(self._sp(meta), Expr._LeftName(self._sp(meta), items[0]), None)

def get_name(self, meta, items) -> Expr.Base:
assert len(items) == 2 and isinstance(items[0], Expr.Base) and isinstance(items[1], str)
return Expr.Get(self._sp(meta), items[0], items[1])
assert (
len(items) == 2 and isinstance(items[0], Expr.Base) and isinstance(items[1].value, str)
)
return Expr.Get(self._sp(meta), items[0], items[1].value)


# _ExprTransformer infix operators
Expand Down
30 changes: 29 additions & 1 deletion tests/runner.t
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ source tests/bash-tap/bash-tap-bootstrap
export PYTHONPATH="$SOURCE_DIR:$PYTHONPATH"
miniwdl="python3 -m WDL"

plan tests 89
plan tests 90

$miniwdl run_self_test
is "$?" "0" "run_self_test"
Expand Down Expand Up @@ -599,3 +599,31 @@ workflow outer {
EOF
MINIWDL__SCHEDULER__SUBWORKFLOW_CONCURRENCY=2 $miniwdl run --dir nested_deadlock outer.wdl
is "$?" "0" "avoid deadlocking on nested subworkflows"

cat << 'EOF' > issue686.wdl
version 1.1
struct ReadGroup {
String ID
String? KS
}
task test_task {
input {
ReadGroup read_group
}
command <<<
if [ -z "~{read_group.KS}" ]
then
echo "KS is empty"
fi
>>>
}
EOF
$miniwdl run issue686.wdl -i '{
"read_group": {
"ID": "test"
}
}'
is "$?" "0" "ensure optional fields in structs initialized from JSON (issue 686 regression)"

0 comments on commit 6b6d906

Please sign in to comment.