Skip to content

Commit

Permalink
Fix alias of optional type
Browse files Browse the repository at this point in the history
  • Loading branch information
yukinarit committed Oct 9, 2023
1 parent 2855b6b commit f8f33df
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 4 deletions.
19 changes: 15 additions & 4 deletions serde/de.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,13 +123,18 @@ def default_deserializer(_cls: Type[Any], obj: Any) -> Any:
"""


def _get_by_aliases(d: Dict[str, str], aliases: List[str]) -> str:
def _get_by_aliases(
d: Dict[str, str], aliases: List[str], raise_error: bool = True
) -> Optional[str]:
if not aliases:
raise KeyError("Tried all aliases, but key not found")
if raise_error:
raise KeyError("Tried all aliases, but key not found")

Check warning on line 131 in serde/de.py

View check run for this annotation

Codecov / codecov/patch

serde/de.py#L131

Added line #L131 was not covered by tests
else:
return None
if aliases[0] in d:
return d[aliases[0]]
else:
return _get_by_aliases(d, aliases[1:])
return _get_by_aliases(d, aliases[1:], raise_error=raise_error)


def _exists_by_aliases(d: Dict[str, str], aliases: List[str]) -> bool:
Expand Down Expand Up @@ -804,7 +809,13 @@ def opt(self, arg: DeField[Any]) -> str:
if arg.iterbased:
exists = f"{arg.data} is not None"
else:
exists = f'{arg.datavar}.get("{arg.conv_name()}") is not None'
name = arg.conv_name()
if arg.alias:
aliases = (f'"{s}"' for s in [name, *arg.alias])
get = f"_get_by_aliases(data, [{','.join(aliases)}], raise_error=False)"
else:
get = f'{arg.datavar}.get("{name}")'
exists = f"{get} is not None"
return f"({self.render(value_arg)}) if {exists} else None"

def list(self, arg: DeField[Any]) -> str:
Expand Down
9 changes: 9 additions & 0 deletions tests/test_basics.py
Original file line number Diff line number Diff line change
Expand Up @@ -573,6 +573,15 @@ class Foo:
assert ff.a == 2


def test_optional_and_alias():
@serde.serde
class Foo:
a: Optional[int] = serde.field(alias=["b"])

assert Foo(1) == serde.json.from_json(Foo, '{"b":1}')
assert Foo(None) == serde.json.from_json(Foo, '{"c":1}')


def test_default_and_rename():
@serde.serde
class Foo:
Expand Down

0 comments on commit f8f33df

Please sign in to comment.