File: json_util.py

package info (click to toggle)
dataclass-wizard 0.39.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 3,112 kB
  • sloc: python: 19,560; makefile: 126; javascript: 23
file content (57 lines) | stat: -rw-r--r-- 1,372 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
"""
JSON Helper Utilities - *only* internally used in ``errors.py``,
i.e. for rendering exceptions.

.. NOTE::
    This module should not be imported anywhere at the *top-level*
    of another library module!

"""
__all__ = [
    'safe_dumps',
]

from dataclasses import is_dataclass
from datetime import datetime, time, date
from enum import Enum
from json import dumps, JSONEncoder
from typing import Any
from uuid import UUID

from ..loader_selection import asdict


class SafeEncoder(JSONEncoder):
    """
    A Customized JSON Encoder, which copies core logic in the
    `dumpers` module to support serialization of more complex
    Python types, such as `datetime` and `Enum`.
    """

    def default(self, o: Any) -> Any:
        """Default function, copies the core (minimal) logic from `dumpers.py`."""

        if is_dataclass(o):
            return asdict(o)

        if isinstance(o, Enum):
            return o.value

        if isinstance(o, UUID):
            return o.hex

        if isinstance(o, (datetime, time)):
            return o.isoformat().replace('+00:00', 'Z', 1)

        if isinstance(o, date):
            return o.isoformat()

        # anything else (Decimal, timedelta, etc.)
        return str(o)


def safe_dumps(o, cls=SafeEncoder, **kwargs):
    try:
        return dumps(o, cls=cls, **kwargs)
    except TypeError:
        return o