Passed
Push — master ( 005733...10033b )
by Ramon
01:08
created

jsons.serializers.default_tuple_serializer()   A

Complexity

Conditions 1

Size

Total Lines 9
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nop 2
dl 0
loc 9
rs 10
c 0
b 0
f 0
1
"""
2
This module contains default serializers. You can override the serialization
3
process of a particular type as follows:
4
5
``jsons.set_serializer(custom_deserializer, SomeClass)``
6
"""
7
from datetime import datetime
8
from enum import EnumMeta
9
from typing import Callable
10
from jsons import dump_impl
11
from jsons._common_impl import RFC3339_DATETIME_PATTERN, snakecase, \
12
    camelcase, pascalcase, lispcase
13
14
15
def default_iterable_serializer(obj, **kwargs) -> list:
16
    """
17
    Serialize the given ``obj`` to a list of serialized objects.
18
    :param obj: the iterable that is to be serialized.
19
    :param kwargs: any keyword arguments that may be given to the serialization
20
    process.
21
    :return: a list of which all elements are serialized.
22
    """
23
    return [dump_impl(elem, **kwargs) for elem in obj]
24
25
26
def default_list_serializer(obj: list, **kwargs) -> list:
27
    """
28
    Serialize the given ``obj`` to a list of serialized objects.
29
    :param obj: the list that is to be serialized.
30
    :param kwargs: any keyword arguments that may be given to the serialization
31
    process.
32
    :return: a list of which all elements are serialized.
33
    """
34
    return default_iterable_serializer(obj, **kwargs)
35
36
37
def default_tuple_serializer(obj: tuple, **kwargs) -> list:
38
    """
39
    Serialize the given ``obj`` to a list of serialized objects.
40
    :param obj: the tuple that is to be serialized.
41
    :param kwargs: any keyword arguments that may be given to the serialization
42
    process.
43
    :return: a list of which all elements are serialized.
44
    """
45
    return default_iterable_serializer(obj, **kwargs)
46
47
48
def default_dict_serializer(obj: dict, strip_nulls: bool = False,
49
                            key_transformer: Callable[[str], str] = None,
50
                            **kwargs) -> dict:
51
    """
52
    Serialize the given ``obj`` to a dict of serialized objects.
53
    :param obj: the dict that is to be serialized.
54
    :param key_transformer: a function that will be applied to all keys in the
55
    resulting dict.
56
    :param strip_nulls: if ``True`` the resulting dict will not contain null
57
    values.
58
    :param kwargs: any keyword arguments that may be given to the serialization
59
    process.
60
    :return: a dict of which all elements are serialized.
61
    """
62
    result = dict()
63
    for key in obj:
64
        dumped_elem = dump_impl(obj[key], key_transformer=key_transformer,
65
                                strip_nulls=strip_nulls, **kwargs)
66
        if not (strip_nulls and dumped_elem is None):
67
            if key_transformer:
68
                key = key_transformer(key)
69
            result[key] = dumped_elem
70
    return result
71
72
73
def default_enum_serializer(obj: EnumMeta, use_enum_name: bool = True,
74
                            **_) -> str:
75
    """
76
    Serialize the given obj. By default, the name of the enum element is
77
    returned.
78
    :param obj: an instance of an enum.
79
    :param use_enum_name: determines whether the name or the value should be
80
    used for serialization.
81
    :param _: not used.
82
    :return: ``obj`` serialized as a string.
83
    """
84
    attr = 'name' if use_enum_name else 'value'
85
    return getattr(obj, attr)
86
87
88
def default_datetime_serializer(obj: datetime, **_) -> str:
89
    """
90
    Serialize the given datetime instance to a string. It uses the RFC3339
91
    pattern. If datetime is a localtime, an offset is provided. If datetime is
92
    in UTC, the result is suffixed with a 'Z'.
93
    :param obj: the datetime instance that is to be serialized.
94
    :param _: not used.
95
    :return: ``datetime`` as an RFC3339 string.
96
    """
97
    timezone = obj.tzinfo
98
    offset = 'Z'
99
    pattern = RFC3339_DATETIME_PATTERN
100
    if timezone:
101
        if timezone.tzname(None) != 'UTC':
102
            offset = timezone.tzname(None).split('UTC')[1]
103
    if obj.microsecond:
104
        pattern += '.%f'
105
    return obj.strftime("{}{}".format(pattern, offset))
106
107
108
def default_primitive_serializer(obj, **_) -> object:
109
    """
110
    Serialize a primitive; simply return the given ``obj``.
111
    :param obj:
112
    :param _: not used.
113
    :return: ``obj``.
114
    """
115
    return obj
116
117
118
def default_object_serializer(obj: object,
119
                              key_transformer: Callable[[str], str] = None,
120
                              strip_nulls: bool = False,
121
                              strip_privates: bool = False,
122
                              strip_properties: bool = False,
123
                              **kwargs) -> dict:
124
    """
125
    Serialize the given ``obj`` to a dict. All values within ``obj`` are also
126
    serialized. If ``key_transformer`` is given, it will be used to transform
127
    the casing (e.g. snake_case) to a different format (e.g. camelCase).
128
    :param obj: the object that is to be serialized.
129
    :param key_transformer: a function that will be applied to all keys in the
130
    resulting dict.
131
    :param strip_nulls: if ``True`` the resulting dict will not contain null
132
    values.
133
    :param strip_privates: if ``True`` the resulting dict will not contain
134
    private attributes (i.e. attributes that start with an underscore).
135
    :param strip_properties: if ``True`` the resulting dict will not contain
136
    values from @properties.
137
    :param kwargs: any keyword arguments that are to be passed to the
138
    serializer functions.
139
    :return: a Python dict holding the values of ``obj``.
140
    """
141
    obj_dict = obj.__dict__ if strip_properties and hasattr(obj, '__dict__') \
142
        else _get_dict_from_obj(obj, strip_privates)
143
    return default_dict_serializer(obj_dict, key_transformer=key_transformer,
144
                                   strip_nulls=strip_nulls,
145
                                   strip_privates=strip_privates, **kwargs)
146
147
148
def _get_dict_from_obj(obj, strip_privates):
149
    return {attr: obj.__getattribute__(attr) for attr in dir(obj)
150
            if not attr.startswith('__')
151
            and not (strip_privates and attr.startswith('_'))
152
            and attr != 'json'
153
            and not isinstance(obj.__getattribute__(attr), Callable)}
154
155
156
# The following default key transformers can be used with the
157
# default_object_serializer and default_dict_serializer.
158
KEY_TRANSFORMER_SNAKECASE = snakecase
159
KEY_TRANSFORMER_CAMELCASE = camelcase
160
KEY_TRANSFORMER_PASCALCASE = pascalcase
161
KEY_TRANSFORMER_LISPCASE = lispcase
162