Source code for scripts.engine.internal.extend_json

from __future__ import annotations

import dataclasses
import json
from typing import Type, TYPE_CHECKING

if TYPE_CHECKING:
    from typing import Dict


####################### UTILITY ############################


[docs]def deserialise_dataclasses(dct): if "__dataclass__" in dct: dataclass_ = ExtendedJsonEncoder.__dataclassses__[dct["__dataclass__"]] del dct["__dataclass__"] return dataclass_(**{k: v if not isinstance(v, dict) else deserialise_dataclasses(v) for k, v in dct.items()}) return dct
[docs]def register_dataclass_with_json(cls): ExtendedJsonEncoder.__dataclassses__[cls.__name__] = cls return cls
####################### JSON ENCODING ############################ JSON_TYPES = [str, int, dict, float, bool, tuple, list, type(None)]
[docs]class ExtendedJsonEncoder(json.JSONEncoder): """ Extend the json Encoder to handle dataclass types """ __dataclassses__: Dict[str, Type] = {}
[docs] def default(self, obj): """ Override the base default method to handle enum and dataclasses """ if dataclasses.is_dataclass(obj): return { **dict(__dataclass__=obj.__class__.__name__), **{field.name: self.default(getattr(obj, field.name)) for field in dataclasses.fields(obj)}, } elif type(obj) in JSON_TYPES: return obj super(ExtendedJsonEncoder, self).default(obj)