Skip to content

Commit

Permalink
Add test for keyed literal unions -- which fails
Browse files Browse the repository at this point in the history
  • Loading branch information
rhaps0dy committed May 10, 2024
1 parent d54db1c commit d70350f
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 20 deletions.
2 changes: 1 addition & 1 deletion databind/src/databind/json/converters.py
Original file line number Diff line number Diff line change
Expand Up @@ -763,7 +763,7 @@ def _check_style_compatibility(self, ctx: Context, style: str, value: t.Any) ->
def convert(self, ctx: Context) -> t.Any:
datatype = ctx.datatype
union: t.Optional[Union]
literal_types: list[TypeHint] = []
literal_types: t.List[TypeHint] = []

if isinstance(datatype, UnionTypeHint):
if datatype.has_none_type():
Expand Down
61 changes: 42 additions & 19 deletions databind/src/databind/json/tests/converters_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
DatetimeConverter,
DecimalConverter,
EnumConverter,
LiteralConverter,
MappingConverter,
OptionalConverter,
PlainDatatypeConverter,
Expand Down Expand Up @@ -328,6 +329,22 @@ def test_union_converter_best_match(direction: Direction) -> None:
assert mapper.convert(direction, 42, t.Union[int, str]) == 42


@pytest.mark.parametrize("direction", (Direction.SERIALIZE, Direction.DESERIALIZE))
def test_union_converter_best_match_literal(direction: Direction) -> None:
mapper = make_mapper([UnionConverter(), PlainDatatypeConverter(), LiteralConverter()])

LiteralUnionType = t.Union[int, t.Literal["hi"], t.Literal["bye"]]

if direction == Direction.DESERIALIZE:
assert mapper.convert(direction, 42, LiteralUnionType) == 42
assert mapper.convert(direction, "hi", LiteralUnionType) == "hi"
assert mapper.convert(direction, "bye", LiteralUnionType) == "bye"
else:
assert mapper.convert(direction, 42, LiteralUnionType) == 42
assert mapper.convert(direction, "hi", LiteralUnionType) == "hi"
assert mapper.convert(direction, "bye", LiteralUnionType) == "bye"


@pytest.mark.parametrize("direction", (Direction.SERIALIZE, Direction.DESERIALIZE))
def test_union_converter_keyed(direction: Direction) -> None:
mapper = make_mapper([UnionConverter(), PlainDatatypeConverter()])
Expand All @@ -339,6 +356,31 @@ def test_union_converter_keyed(direction: Direction) -> None:
assert mapper.convert(direction, 42, th) == {"int": 42}


@pytest.mark.xfail
@pytest.mark.parametrize("direction", (Direction.SERIALIZE, Direction.DESERIALIZE))
def test_union_converter_keyed_literal(direction: Direction) -> None:
mapper = make_mapper([UnionConverter(), PlainDatatypeConverter(), LiteralConverter()])

th = te.Annotated[
t.Union[int, t.Literal["hi"], t.Literal["bye"]],
Union({"int": int, "HiType": t.Literal["hi"], "ByeType": t.Literal["bye"]}, style=Union.KEYED),
]
if direction == Direction.DESERIALIZE:
assert mapper.convert(direction, {"int": 42}, th) == 42
assert mapper.convert(direction, {"HiType": "hi"}, th) == "hi"
assert mapper.convert(direction, {"ByeType": "bye"}, th) == "bye"

with pytest.raises(ConversionError):
mapper.convert(direction, {"ByeType": "hi"}, th)
else:
assert mapper.convert(direction, 42, th) == {"int": 42}
assert mapper.convert(direction, "hi", th) == {"HiType": "hi"}
assert mapper.convert(direction, "bye", th) == {"ByeType": "bye"}

with pytest.raises(ConversionError):
mapper.convert(direction, {"ByeType": "hi"}, th)


@pytest.mark.parametrize("direction", (Direction.SERIALIZE, Direction.DESERIALIZE))
def test_union_converter_flat_plain_types_not_supported(direction: Direction) -> None:
mapper = make_mapper([UnionConverter(), PlainDatatypeConverter()])
Expand Down Expand Up @@ -713,22 +755,3 @@ def of(cls, v: str) -> "MyCls":
mapper = make_mapper([JsonConverterSupport()])
assert mapper.serialize(MyCls(), MyCls) == "MyCls"
assert mapper.deserialize("MyCls", MyCls) == MyCls()


def test_union_literal():
mapper = make_mapper([UnionConverter(), PlainDatatypeConverter()])

IntType = int | t.Literal["hi", "bye"]
StrType = str | t.Literal["hi", "bye"]

assert mapper.serialize("hi", IntType) == "hi"
assert mapper.serialize(2, IntType) == 2

assert mapper.serialize("bye", StrType) == "bye"
assert mapper.serialize("other", StrType) == "other"

assert mapper.deserialize("hi", IntType) == "hi"
assert mapper.deserialize(2, IntType) == 2

assert mapper.deserialize("bye", StrType) == "bye"
assert mapper.deserialize("other", StrType) == "other"

0 comments on commit d70350f

Please sign in to comment.