Skip to content

Commit 47a4b0a

Browse files
authored
Merge pull request #354 from kmsquire/fix-default-alias
Fix combination of alias and default
2 parents a9f44d5 + 265a570 commit 47a4b0a

File tree

2 files changed

+63
-2
lines changed

2 files changed

+63
-2
lines changed

serde/de.py

+13-1
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,13 @@ def _get_by_aliases(d: Dict[str, str], aliases: List[str]):
123123
return _get_by_aliases(d, aliases[1:])
124124

125125

126+
def _exists_by_aliases(d: Dict[str, str], aliases: List[str]):
127+
for alias in aliases:
128+
if alias in d:
129+
return True
130+
return False
131+
132+
126133
def _make_deserialize(
127134
cls_name: str,
128135
fields,
@@ -262,6 +269,7 @@ def wrap(cls: Type[Any]):
262269
g['NoCheck'] = NoCheck
263270
g['coerce'] = coerce
264271
g['_get_by_aliases'] = _get_by_aliases
272+
g['_exists_by_aliases'] = _exists_by_aliases
265273
if deserialize:
266274
g['serde_custom_class_deserializer'] = functools.partial(
267275
serde_custom_class_deserializer, custom=deserializer
@@ -877,7 +885,11 @@ def literal(self, arg: DeField) -> str:
877885
return f"serde_scope.funcs['{func_name}'](cls=cls, data={arg.data}, reuse_instances=reuse_instances)"
878886

879887
def default(self, arg: DeField, code: str) -> str:
880-
exists = f'"{arg.conv_name()}" in {arg.datavar}'
888+
if arg.alias:
889+
aliases = map(lambda s: f'"{s}"', [arg.name, *arg.alias])
890+
exists = f'_exists_by_aliases({arg.datavar}, [{",".join(aliases)}])'
891+
else:
892+
exists = f'"{arg.conv_name()}" in {arg.datavar}'
881893
if has_default(arg):
882894
return f'({code}) if {exists} else serde_scope.defaults["{arg.name}"]'
883895
elif has_default_factory(arg):

tests/test_basics.py

+50-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,17 @@
44
import logging
55
import pathlib
66
import uuid
7-
from typing import ClassVar, DefaultDict, Dict, FrozenSet, List, Optional, Set, Tuple, Union
7+
from typing import (
8+
ClassVar,
9+
DefaultDict,
10+
Dict,
11+
FrozenSet,
12+
List,
13+
Optional,
14+
Set,
15+
Tuple,
16+
Union,
17+
)
818

919
import pytest
1020

@@ -536,6 +546,45 @@ class Foo:
536546
assert ff.a == 10
537547

538548

549+
def test_default_and_alias():
550+
@serde.serde
551+
class Foo:
552+
a: int = serde.field(default=2, alias=["b", "c", "d"])
553+
554+
f = Foo(a=1)
555+
assert '{"a":1}' == serde.json.to_json(f)
556+
ff = serde.json.from_json(Foo, '{"b":10}')
557+
assert ff.a == 10
558+
ff = serde.json.from_json(Foo, '{"e":10}')
559+
assert ff.a == 2
560+
561+
562+
def test_default_and_rename():
563+
@serde.serde
564+
class Foo:
565+
a: int = serde.field(default=2, rename="z")
566+
567+
f = Foo(a=1)
568+
assert '{"z":1}' == serde.json.to_json(f)
569+
ff = serde.json.from_json(Foo, '{"z":10}')
570+
assert ff.a == 10
571+
fff = serde.json.from_json(Foo, '{"a":10}')
572+
assert fff.a == 2
573+
574+
575+
def test_default_rename_and_alias():
576+
@serde.serde
577+
class Foo:
578+
a: int = serde.field(default=2, rename="z", alias=["b", "c", "d"])
579+
580+
f = Foo(a=1)
581+
assert '{"z":1}' == serde.json.to_json(f)
582+
ff = serde.json.from_json(Foo, '{"b":10}')
583+
assert ff.a == 10
584+
ff = serde.json.from_json(Foo, '{"e":10}')
585+
assert ff.a == 2
586+
587+
539588
@pytest.mark.parametrize(
540589
'se,de', (format_dict + format_json + format_msgpack + format_yaml + format_toml + format_pickle)
541590
)

0 commit comments

Comments
 (0)