|
1 | 1 | from dataclasses import dataclass |
2 | 2 | from datetime import datetime |
3 | 3 | from os import path |
4 | | -from typing import Any, cast, TypeVar, Generic |
| 4 | +from typing import Any, cast, Type, TypeVar |
5 | 5 |
|
6 | 6 | from jsons import ( |
7 | 7 | dump, |
|
17 | 17 | default_nonetype_deserializer, |
18 | 18 | ) |
19 | 19 |
|
| 20 | +S = TypeVar("S", bound="Serializable") |
20 | 21 | T = TypeVar("T") |
21 | 22 |
|
22 | 23 | JSON_FILE_EXTENSION: str = ".json" |
|
28 | 29 |
|
29 | 30 |
|
30 | 31 | @dataclass |
31 | | -class Serializable(Generic[T]): |
| 32 | +class Serializable: |
32 | 33 | """ |
33 | 34 | Serializable class with methods to convert to json |
34 | 35 | """ |
@@ -61,35 +62,29 @@ def to_json_file( |
61 | 62 | write_json_file(self, file_name, file_path, strip_privates) |
62 | 63 |
|
63 | 64 | @classmethod |
64 | | - def from_json(cls, data: str) -> T: |
| 65 | + def from_json(cls: Type[S], data: str) -> S: |
65 | 66 | """ |
66 | 67 | Deserialize the provided data string into the specified instance |
67 | 68 | :param data: JSON string |
68 | 69 | """ |
69 | | - set_deserializers() |
70 | | - return cast(T, loads(data, cls)) |
| 70 | + return read_json(data, cls) |
71 | 71 |
|
72 | 72 | @classmethod |
73 | | - def from_json_object(cls, data: object) -> T: |
| 73 | + def from_json_object(cls: Type[S], data: object) -> S: |
74 | 74 | """ |
75 | 75 | Deserialize the provided data object into the specified instance |
76 | 76 | :param data: JSON object |
77 | 77 | """ |
78 | | - set_deserializers() |
79 | | - return cast(T, load(data, cls)) |
| 78 | + return read_json_object(data, cls) |
80 | 79 |
|
81 | 80 | @classmethod |
82 | | - def from_json_file(cls, file_name: str, file_path: str = "") -> T: |
| 81 | + def from_json_file(cls: Type[S], file_name: str, file_path: str = "") -> S: |
83 | 82 | """ |
84 | 83 | Deserialize the provided file into the specified instance |
85 | 84 | :param file_name: File name |
86 | 85 | :param file_path: File path |
87 | 86 | """ |
88 | | - json_file_path: str = path.join(file_path, file_name + JSON_FILE_EXTENSION) |
89 | | - with open(json_file_path, READ) as json_file: |
90 | | - data = json_file.read() |
91 | | - target = cls.from_json(data) |
92 | | - return target |
| 87 | + return read_json_file(cls, file_name, file_path) |
93 | 88 |
|
94 | 89 |
|
95 | 90 | def _remove_key(obj: Any, key_to_remove: str) -> Any: |
@@ -169,6 +164,44 @@ def write_json_file( |
169 | 164 | json_file.write(write_json(object_to_write, strip_privates)) |
170 | 165 |
|
171 | 166 |
|
| 167 | +def read_json(data: Any, class_out: Type[T]) -> T: |
| 168 | + """ |
| 169 | + Deserialize json file to object |
| 170 | + :param data: Json file data |
| 171 | + :param class_out: Object type |
| 172 | + :return: Deserialized object |
| 173 | + """ |
| 174 | + set_deserializers() |
| 175 | + return cast(T, loads(data, class_out)) |
| 176 | + |
| 177 | + |
| 178 | +def read_json_object(data: Any, class_out: Type[T]) -> T: |
| 179 | + """ |
| 180 | + Deserialize json file to object |
| 181 | + :param data: Json file data |
| 182 | + :param class_out: Object type |
| 183 | + :return: Deserialized object |
| 184 | + """ |
| 185 | + set_deserializers() |
| 186 | + return cast(T, load(data, class_out)) |
| 187 | + |
| 188 | + |
| 189 | +def read_json_file(class_out: Type[T], file_name: str, file_path: str = "") -> T: |
| 190 | + """ |
| 191 | + Deserialize json file to object |
| 192 | + :param class_out: Object type |
| 193 | + :param file_name: File name |
| 194 | + :param file_path: File path |
| 195 | + :return: Deserialized object |
| 196 | + """ |
| 197 | + set_deserializers() |
| 198 | + json_file_path: str = path.join(file_path, file_name + JSON_FILE_EXTENSION) |
| 199 | + with open(json_file_path, READ) as json_file: |
| 200 | + data = json_file.read() |
| 201 | + target: T = read_json(data, class_out) |
| 202 | + return target |
| 203 | + |
| 204 | + |
172 | 205 | def set_serializers() -> None: |
173 | 206 | """Set serializers for jsons to use to cast specific classes""" |
174 | 207 |
|
|
0 commit comments