1 from __future__ import annotations

2

3 import sys

4

5 import pytest

6

7 from muutils.json_serialize import SerializableDataclass, serializable_dataclass

8

9 SUPPORTS_KW_ONLY: bool = sys.version_info >= (3, 10)

10

11 print(f"{SUPPORTS_KW_ONLY = }")

12

13

14@serializable_dataclass

15 class Person(SerializableDataclass):

16 first_name: str

17 last_name: str

18

19 @property

20 def full_name(self) -> str:

21 return f"{self.first_name} {self.last_name}"

22

23

24@serializable_dataclass(

25 kw_only=SUPPORTS_KW_ONLY, properties_to_serialize=["full_name", "full_title"]

26)

27 class TitledPerson(Person):

28 title: str

29

30 @property

31 def full_title(self) -> str:

32 return f"{self.title} {self.full_name}"

33

34

35@serializable_dataclass(

36 kw_only=SUPPORTS_KW_ONLY,

37 properties_to_serialize=["full_name", "not_a_real_property"],

38)

39 class AgedPerson_not_valid(Person):

40 title: str

41

42 @property

43 def full_title(self) -> str:

44 return f"{self.title} {self.full_name}"

45

46

47 def test_invalid_properties_to_serialize():

48 instance = AgedPerson_not_valid(first_name="Jane", last_name="Smith", title="Dr.")

49

50 with pytest.raises(AttributeError):

51 instance.serialize()

52

53

54 def test_serialize_person():

55 instance = Person(first_name="John", last_name="Doe")

56

57 serialized = instance.serialize()

58

59 assert serialized == {

60 "first_name": "John",

61 "last_name": "Doe",

62 "__format__": "Person(SerializableDataclass)",

63 }

64

65 recovered = Person.load(serialized)

66

67 assert recovered == instance

68

69

70 def test_serialize_titled_person():

71 instance = TitledPerson(first_name="Jane", last_name="Smith", title="Dr.")

72

73 if SUPPORTS_KW_ONLY:

74 with pytest.raises(TypeError):

75 TitledPerson("Jane", "Smith", "Dr.")

76

77 serialized = instance.serialize()

78

79 assert serialized == {

80 "first_name": "Jane",

81 "last_name": "Smith",

82 "title": "Dr.",

83 "__format__": "TitledPerson(SerializableDataclass)",

84 "full_name": "Jane Smith",

85 "full_title": "Dr. Jane Smith",

86 }

87

88 recovered = TitledPerson.load(serialized)

89

90 assert recovered == instance