Skip to content

Commit

Permalink
allow Object type coercion to Map
Browse files Browse the repository at this point in the history
regression #538
  • Loading branch information
mlin committed Dec 27, 2021
1 parent d5cf854 commit b8230e2
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 1 deletion.
6 changes: 6 additions & 0 deletions WDL/Type.py
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,12 @@ def coerces(self, rhs: Base, check_quant: bool = True) -> bool:
if not rhs_members[opt_k].optional:
return False
return True
if isinstance(rhs, Map):
# Member names must coerce to the map key type, and each member type must coerce to the
# map value type.
return String().coerces(rhs.item_type[0]) and all(
vt.coerces(rhs.item_type[1]) for vt in self.members.values()
)
if isinstance(rhs, Any):
return self._check_optional(rhs, check_quant)
return False
Expand Down
3 changes: 2 additions & 1 deletion WDL/Value.py
Original file line number Diff line number Diff line change
Expand Up @@ -507,11 +507,11 @@ def fail(msg):
for k, v in self.value.items():
if not (isinstance(v, Null) and value_type.optional):
map_key = None
map_value = None
try:
map_key = String(k).coerce(key_type)
except Error.RuntimeError:
fail(f"cannot coerce member name {k} to {key_type} map key")
map_value = None
if self.type.members[k].coerces(value_type):
with suppress(Error.RuntimeError):
map_value = v.coerce(value_type)
Expand All @@ -521,6 +521,7 @@ def fail(msg):
f" {self.type.members[k]} {k} to {value_type} map value"
)
entries.append((map_key, map_value))
assert self.type.coerces(desired_type)
return Map(desired_type.item_type, entries)

def __str__(self) -> Any:
Expand Down
18 changes: 18 additions & 0 deletions tests/test_5stdlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -887,6 +887,24 @@ def test_issue524(self):
}
""", expected_exception=WDL.Error.EvalError)

def test_issue538(self):
# more struct init regression
self._test_task(R"""
version 1.0
struct StructWithMap { Map[String, String] map }
task RoundTripJson {
input {}
StructWithMap example = object {
map: { "foo":"bar", "fizz":"buzz" }
}
String dbg = read_string(write_json(example))
command {}
output {
StructWithMap result = read_json(write_json(example))
}
}
""")

def test_bad_object(self):
self._test_task(R"""
version 1.0
Expand Down

0 comments on commit b8230e2

Please sign in to comment.