JsonSerializable.loads()   A
last analyzed

Complexity

Conditions 1

Size

Total Lines 10
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 10
rs 10
c 0
b 0
f 0
cc 1
nop 3
1
from typing import Optional, Type
2
3
from jsons._common_impl import StateHolder, T
4
from jsons._dump_impl import dump, dumps, dumpb
5
from jsons._fork_impl import fork
6
from jsons._lizers_impl import set_serializer, set_deserializer
7
from jsons._load_impl import load, loads, loadb
8
9
10
class JsonSerializable(StateHolder):
11
    """
12
    This class offers an alternative to using the ``jsons.load`` and
13
    ``jsons.dump`` methods. An instance of a class that inherits from
14
    ``JsonSerializable`` has the ``json`` property, which value is equivalent
15
    to calling ``jsons.dump`` on that instance. Furthermore, you can call
16
    ``from_json`` on that class, which is equivalent to calling ``json.load``
17
    with that class as an argument.
18
    """
19
20
    @classmethod
21
    def fork(cls, name: Optional[str] = None) -> Type['JsonSerializable']:
22
        """
23
        Create a 'fork' of ``JsonSerializable``: a new ``type`` with a separate
24
        configuration of serializers and deserializers.
25
        :param name: the ``__name__`` of the new ``type``.
26
        :return: a new ``type`` based on ``JsonSerializable``.
27
        """
28
        return fork(cls, name=name)
29
30
    @classmethod
31
    def with_dump(cls, fork: Optional[bool] = False, **kwargs) \
32
            -> Type['JsonSerializable']:
33
        """
34
        Return a class (``type``) that is based on JsonSerializable with the
35
        ``dump`` method being automatically provided the given ``kwargs``.
36
37
        **Example:**
38
39
        >>> custom_serializable = JsonSerializable\
40
                .with_dump(key_transformer=KEY_TRANSFORMER_CAMELCASE)
41
        >>> class Person(custom_serializable):
42
        ...     def __init__(self, my_name):
43
        ...         self.my_name = my_name
44
        >>> p = Person('John')
45
        >>> p.json
46
        {'myName': 'John'}
47
48
        :param kwargs: the keyword args that are automatically provided to the
49
        ``dump`` method.
50
        :param fork: determines that a new fork is to be created.
51
        :return: a class with customized behavior.
52
        """
53
54
        def _wrapper(inst, **kwargs_):
55
            return dump(inst, **{**kwargs_, **kwargs})
56
57
        type_ = cls.fork() if fork else cls
58
        type_.dump = _wrapper
59
        return type_
60
61
    @classmethod
62
    def with_load(cls, fork: Optional[bool] = False, **kwargs) \
63
            -> Type['JsonSerializable']:
64
        """
65
        Return a class (``type``) that is based on JsonSerializable with the
66
        ``load`` method being automatically provided the given ``kwargs``.
67
68
        **Example:**
69
70
        >>> custom_serializable = JsonSerializable\
71
                .with_load(key_transformer=KEY_TRANSFORMER_SNAKECASE)
72
        >>> class Person(custom_serializable):
73
        ...     def __init__(self, my_name):
74
        ...         self.my_name = my_name
75
        >>> p_json = {'myName': 'John'}
76
        >>> p = Person.from_json(p_json)
77
        >>> p.my_name
78
        'John'
79
80
        :param kwargs: the keyword args that are automatically provided to the
81
        ``load`` method.
82
        :param fork: determines that a new fork is to be created.
83
        :return: a class with customized behavior.
84
        """
85
86
        @classmethod
87
        def _wrapper(cls_, inst, **kwargs_):
88
            return load(inst, cls_, fork_inst=cls_, **{**kwargs_, **kwargs})
89
90
        type_ = cls.fork() if fork else cls
91
        type_.load = _wrapper
92
        return type_
93
94
    @property
95
    def json(self) -> object:
96
        """
97
        See ``jsons.dump``.
98
        :return: this instance in a JSON representation (dict).
99
        """
100
        return self.dump()
101
102
    def __str__(self) -> str:
103
        """
104
        See ``jsons.dumps``.
105
        :return: this instance as a JSON string.
106
        """
107
        return self.dumps()
108
109
    @classmethod
110
    def from_json(cls: Type[T], json_obj: object, **kwargs) -> T:
111
        """
112
        See ``jsons.load``.
113
        :param json_obj: a JSON representation of an instance of the inheriting
114
        class
115
        :param kwargs: the keyword args are passed on to the deserializer
116
        function.
117
        :return: an instance of the inheriting class.
118
        """
119
        return cls.load(json_obj, **kwargs)
120
121
    def dump(self, **kwargs) -> object:
122
        """
123
        See ``jsons.dump``.
124
        :param kwargs: the keyword args are passed on to the serializer
125
        function.
126
        :return: this instance in a JSON representation (dict).
127
        """
128
        return dump(self, fork_inst=self.__class__, **kwargs)
129
130
    @classmethod
131
    def load(cls: Type[T], json_obj: object, **kwargs) -> T:
132
        """
133
        See ``jsons.load``.
134
        :param kwargs: the keyword args are passed on to the serializer
135
        function.
136
        :param json_obj: the object that is loaded into an instance of `cls`.
137
        :return: this instance in a JSON representation (dict).
138
        """
139
        return load(json_obj, cls, fork_inst=cls, **kwargs)
140
141
    def dumps(self, **kwargs) -> str:
142
        """
143
        See ``jsons.dumps``.
144
        :param kwargs: the keyword args are passed on to the serializer
145
        function.
146
        :return: this instance as a JSON string.
147
        """
148
        return dumps(self, fork_inst=self.__class__, **kwargs)
149
150
    @classmethod
151
    def loads(cls: Type[T], json_obj: str, **kwargs) -> T:
152
        """
153
        See ``jsons.loads``.
154
        :param kwargs: the keyword args are passed on to the serializer
155
        function.
156
        :param json_obj: the object that is loaded into an instance of `cls`.
157
        :return: this instance in a JSON representation (dict).
158
        """
159
        return loads(json_obj, cls, fork_inst=cls, **kwargs)
160
161
    def dumpb(self, **kwargs) -> bytes:
162
        """
163
        See ``jsons.dumpb``.
164
        :param kwargs: the keyword args are passed on to the serializer
165
        function.
166
        :return: this instance as a JSON string.
167
        """
168
        return dumpb(self, fork_inst=self.__class__, **kwargs)
169
170
    @classmethod
171
    def loadb(cls: Type[T], json_obj: bytes, **kwargs) -> T:
172
        """
173
        See ``jsons.loadb``.
174
        :param kwargs: the keyword args are passed on to the serializer
175
        function.
176
        :param json_obj: the object that is loaded into an instance of `cls`.
177
        :return: this instance in a JSON representation (dict).
178
        """
179
        return loadb(json_obj, cls, fork_inst=cls, **kwargs)
180
181
    @classmethod
182
    def set_serializer(cls: Type[T],
183
                       func: callable,
184
                       cls_: type,
185
                       high_prio: Optional[bool] = True,
186
                       fork: Optional[bool] = False) -> T:
187
        """
188
        See ``jsons.set_serializer``.
189
        :param func: the serializer function.
190
        :param cls_: the type this serializer can handle.
191
        :param high_prio: determines the order in which is looked for the
192
        callable.
193
        :param fork: determines that a new fork is to be created.
194
        :return: the type on which this method is invoked or its fork.
195
        """
196
        type_ = cls.fork() if fork else cls
197
        set_serializer(func, cls_, high_prio, type_)
198
        return type_
199
200
    @classmethod
201
    def set_deserializer(cls: Type[T],
202
                         func: callable,
203
                         cls_: type,
204
                         high_prio: Optional[bool] = True,
205
                         fork: Optional[bool] = False) -> T:
206
        """
207
        See ``jsons.set_deserializer``.
208
        :param func: the deserializer function.
209
        :param cls_: the type this serializer can handle.
210
        :param high_prio: determines the order in which is looked for the
211
        callable.
212
        :param fork: determines that a new fork is to be created.
213
        :return: the type on which this method is invoked or its fork.
214
        """
215
        type_ = cls.fork() if fork else cls
216
        set_deserializer(func, cls_, high_prio, type_)
217
        return type_
218