Skip to content

Commit d70350f

Browse files
committed
Add test for keyed literal unions -- which fails
1 parent d54db1c commit d70350f

File tree

2 files changed

+43
-20
lines changed

2 files changed

+43
-20
lines changed

databind/src/databind/json/converters.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -763,7 +763,7 @@ def _check_style_compatibility(self, ctx: Context, style: str, value: t.Any) ->
763763
def convert(self, ctx: Context) -> t.Any:
764764
datatype = ctx.datatype
765765
union: t.Optional[Union]
766-
literal_types: list[TypeHint] = []
766+
literal_types: t.List[TypeHint] = []
767767

768768
if isinstance(datatype, UnionTypeHint):
769769
if datatype.has_none_type():

databind/src/databind/json/tests/converters_test.py

Lines changed: 42 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
DatetimeConverter,
3131
DecimalConverter,
3232
EnumConverter,
33+
LiteralConverter,
3334
MappingConverter,
3435
OptionalConverter,
3536
PlainDatatypeConverter,
@@ -328,6 +329,22 @@ def test_union_converter_best_match(direction: Direction) -> None:
328329
assert mapper.convert(direction, 42, t.Union[int, str]) == 42
329330

330331

332+
@pytest.mark.parametrize("direction", (Direction.SERIALIZE, Direction.DESERIALIZE))
333+
def test_union_converter_best_match_literal(direction: Direction) -> None:
334+
mapper = make_mapper([UnionConverter(), PlainDatatypeConverter(), LiteralConverter()])
335+
336+
LiteralUnionType = t.Union[int, t.Literal["hi"], t.Literal["bye"]]
337+
338+
if direction == Direction.DESERIALIZE:
339+
assert mapper.convert(direction, 42, LiteralUnionType) == 42
340+
assert mapper.convert(direction, "hi", LiteralUnionType) == "hi"
341+
assert mapper.convert(direction, "bye", LiteralUnionType) == "bye"
342+
else:
343+
assert mapper.convert(direction, 42, LiteralUnionType) == 42
344+
assert mapper.convert(direction, "hi", LiteralUnionType) == "hi"
345+
assert mapper.convert(direction, "bye", LiteralUnionType) == "bye"
346+
347+
331348
@pytest.mark.parametrize("direction", (Direction.SERIALIZE, Direction.DESERIALIZE))
332349
def test_union_converter_keyed(direction: Direction) -> None:
333350
mapper = make_mapper([UnionConverter(), PlainDatatypeConverter()])
@@ -339,6 +356,31 @@ def test_union_converter_keyed(direction: Direction) -> None:
339356
assert mapper.convert(direction, 42, th) == {"int": 42}
340357

341358

359+
@pytest.mark.xfail
360+
@pytest.mark.parametrize("direction", (Direction.SERIALIZE, Direction.DESERIALIZE))
361+
def test_union_converter_keyed_literal(direction: Direction) -> None:
362+
mapper = make_mapper([UnionConverter(), PlainDatatypeConverter(), LiteralConverter()])
363+
364+
th = te.Annotated[
365+
t.Union[int, t.Literal["hi"], t.Literal["bye"]],
366+
Union({"int": int, "HiType": t.Literal["hi"], "ByeType": t.Literal["bye"]}, style=Union.KEYED),
367+
]
368+
if direction == Direction.DESERIALIZE:
369+
assert mapper.convert(direction, {"int": 42}, th) == 42
370+
assert mapper.convert(direction, {"HiType": "hi"}, th) == "hi"
371+
assert mapper.convert(direction, {"ByeType": "bye"}, th) == "bye"
372+
373+
with pytest.raises(ConversionError):
374+
mapper.convert(direction, {"ByeType": "hi"}, th)
375+
else:
376+
assert mapper.convert(direction, 42, th) == {"int": 42}
377+
assert mapper.convert(direction, "hi", th) == {"HiType": "hi"}
378+
assert mapper.convert(direction, "bye", th) == {"ByeType": "bye"}
379+
380+
with pytest.raises(ConversionError):
381+
mapper.convert(direction, {"ByeType": "hi"}, th)
382+
383+
342384
@pytest.mark.parametrize("direction", (Direction.SERIALIZE, Direction.DESERIALIZE))
343385
def test_union_converter_flat_plain_types_not_supported(direction: Direction) -> None:
344386
mapper = make_mapper([UnionConverter(), PlainDatatypeConverter()])
@@ -713,22 +755,3 @@ def of(cls, v: str) -> "MyCls":
713755
mapper = make_mapper([JsonConverterSupport()])
714756
assert mapper.serialize(MyCls(), MyCls) == "MyCls"
715757
assert mapper.deserialize("MyCls", MyCls) == MyCls()
716-
717-
718-
def test_union_literal():
719-
mapper = make_mapper([UnionConverter(), PlainDatatypeConverter()])
720-
721-
IntType = int | t.Literal["hi", "bye"]
722-
StrType = str | t.Literal["hi", "bye"]
723-
724-
assert mapper.serialize("hi", IntType) == "hi"
725-
assert mapper.serialize(2, IntType) == 2
726-
727-
assert mapper.serialize("bye", StrType) == "bye"
728-
assert mapper.serialize("other", StrType) == "other"
729-
730-
assert mapper.deserialize("hi", IntType) == "hi"
731-
assert mapper.deserialize(2, IntType) == 2
732-
733-
assert mapper.deserialize("bye", StrType) == "bye"
734-
assert mapper.deserialize("other", StrType) == "other"

0 commit comments

Comments
 (0)