From ea8203f8c358be0829e2d31a88e05c4e07ecd162 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Allaire?= Date: Wed, 22 Nov 2023 16:59:14 -0500 Subject: [PATCH 1/4] Fix: Set handling in compat.py iter_types for custom serializer/deserializer --- serde/compat.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/serde/compat.py b/serde/compat.py index 9dd54ba9..6e9b3e7d 100644 --- a/serde/compat.py +++ b/serde/compat.py @@ -385,8 +385,14 @@ def recursive(cls: TypeLike) -> None: lst.add(Union) for arg in type_args(cls): recursive(arg) - elif is_list(cls) or is_set(cls): + elif is_list(cls): + lst.add(List) + args = type_args(cls) + if args: + recursive(args[0]) + elif is_set(cls): lst.add(List) + lst.add(Set) args = type_args(cls) if args: recursive(args[0]) From 79433a40bea39bb1c3702bdddb05b3223c9576aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Allaire?= Date: Wed, 22 Nov 2023 17:05:15 -0500 Subject: [PATCH 2/4] Added test coverage for Set handling with custom serializer/deserializers --- tests/test_compat.py | 4 +++- tests/test_custom.py | 12 ++++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/tests/test_compat.py b/tests/test_compat.py index 0731f835..b9f61d90 100644 --- a/tests/test_compat.py +++ b/tests/test_compat.py @@ -98,6 +98,7 @@ def test_iter_types(): assert {Pri, int, str, float, bool} == set(iter_types(Pri)) assert {Dict, str, Pri, int, float, bool} == set(iter_types(Dict[str, Pri])) assert {List, str} == set(iter_types(List[str])) + assert {List, Set, str} == set(iter_types(Set[str])) assert {Tuple, int, str, bool, float} == set(iter_types(Tuple[int, str, bool, float])) assert {Tuple, int, Ellipsis} == set(iter_types(Tuple[int, ...])) assert {PriOpt, Optional, int, str, float, bool} == set(iter_types(PriOpt)) @@ -110,8 +111,9 @@ class Foo: d: Optional[str] = None e: Union[str, int] = 10 f: List[int] = serde.field(default_factory=list) + g: Set = serde.field(default_factory=set) - assert {Foo, datetime, Optional, str, Union, List, int} == set(iter_types(Foo)) + assert {Foo, datetime, Optional, str, Union, List, Set, int} == set(iter_types(Foo)) def test_iter_unions(): diff --git a/tests/test_custom.py b/tests/test_custom.py index 6946fde1..4edfd759 100644 --- a/tests/test_custom.py +++ b/tests/test_custom.py @@ -2,7 +2,7 @@ Tests for custom serializer/deserializer. """ from datetime import datetime -from typing import List, Optional, Union +from typing import List, Optional, Union, Set import pytest @@ -92,14 +92,18 @@ class Foo: d: Optional[str] = None e: Union[str, int] = 10 f: List[int] = field(default_factory=list) + g: Set[str] = field(default_factory=set) dt = datetime(2021, 1, 1, 0, 0, 0) - f = Foo(10, dt, dt, f=[1, 2, 3]) + f = Foo(10, dt, dt, f=[1, 2, 3], g={4, 5, 6}) - assert to_json(f) == '{"a":10,"b":"01/01/21","c":"01/01/21","d":null,"e":10,"f":[1,2,3]}' + assert ( + to_json(f) + == '{"a":10,"b":"01/01/21","c":"01/01/21","d":null,"e":10,"f":[1,2,3],"g":[4,5,6]}' + ) assert f == from_json(Foo, to_json(f)) - assert to_tuple(f) == (10, "01/01/21", "01/01/21", None, 10, [1, 2, 3]) + assert to_tuple(f) == (10, "01/01/21", "01/01/21", None, 10, [1, 2, 3], {4, 5, 6}) assert f == from_tuple(Foo, to_tuple(f)) def fallback(_, __): From 00b1cfb184384e757b95d61da4c8c3f9287d0ed4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Allaire?= Date: Wed, 22 Nov 2023 17:27:55 -0500 Subject: [PATCH 3/4] Fix test for python3.8 --- tests/test_compat.py | 2 +- tests/test_custom.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_compat.py b/tests/test_compat.py index b9f61d90..9a1b87fc 100644 --- a/tests/test_compat.py +++ b/tests/test_compat.py @@ -111,7 +111,7 @@ class Foo: d: Optional[str] = None e: Union[str, int] = 10 f: List[int] = serde.field(default_factory=list) - g: Set = serde.field(default_factory=set) + g: Set[int] = serde.field(default_factory=set) assert {Foo, datetime, Optional, str, Union, List, Set, int} == set(iter_types(Foo)) diff --git a/tests/test_custom.py b/tests/test_custom.py index 4edfd759..815950da 100644 --- a/tests/test_custom.py +++ b/tests/test_custom.py @@ -92,7 +92,7 @@ class Foo: d: Optional[str] = None e: Union[str, int] = 10 f: List[int] = field(default_factory=list) - g: Set[str] = field(default_factory=set) + g: Set[int] = field(default_factory=set) dt = datetime(2021, 1, 1, 0, 0, 0) f = Foo(10, dt, dt, f=[1, 2, 3], g={4, 5, 6}) From 63b55e4cef0b47c472ccc26a440ea092ec294e39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Allaire?= Date: Mon, 27 Nov 2023 15:31:48 -0500 Subject: [PATCH 4/4] Removed List in iter_types if type is Set --- serde/compat.py | 1 - tests/test_compat.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/serde/compat.py b/serde/compat.py index 6e9b3e7d..ef56e47c 100644 --- a/serde/compat.py +++ b/serde/compat.py @@ -391,7 +391,6 @@ def recursive(cls: TypeLike) -> None: if args: recursive(args[0]) elif is_set(cls): - lst.add(List) lst.add(Set) args = type_args(cls) if args: diff --git a/tests/test_compat.py b/tests/test_compat.py index 9a1b87fc..1eaffa9f 100644 --- a/tests/test_compat.py +++ b/tests/test_compat.py @@ -98,7 +98,7 @@ def test_iter_types(): assert {Pri, int, str, float, bool} == set(iter_types(Pri)) assert {Dict, str, Pri, int, float, bool} == set(iter_types(Dict[str, Pri])) assert {List, str} == set(iter_types(List[str])) - assert {List, Set, str} == set(iter_types(Set[str])) + assert {Set, str} == set(iter_types(Set[str])) assert {Tuple, int, str, bool, float} == set(iter_types(Tuple[int, str, bool, float])) assert {Tuple, int, Ellipsis} == set(iter_types(Tuple[int, ...])) assert {PriOpt, Optional, int, str, float, bool} == set(iter_types(PriOpt))