[O] json support more types

This commit is contained in:
Hykilpikonna
2022-12-19 01:10:31 -05:00
parent 1325224fd8
commit cb6aff290d
+29 -13
View File
@@ -4,9 +4,11 @@ import base64
import dataclasses
import datetime
import hashlib
import inspect
import io
import json
import pickle
from enum import EnumType, Enum
from pathlib import Path
from types import SimpleNamespace
from typing import Any
@@ -37,13 +39,7 @@ def pickle_decode(by: bytes) -> Any:
return pickle.load(bio)
class EnhancedJSONEncoder(json.JSONEncoder):
"""
An improvement to the json.JSONEncoder class, which supports:
encoding for dataclasses, encoding for datetime, and sets
"""
def default(self, o: object) -> object:
def infer(o: object) -> object | None:
# Support encoding dataclasses
# https://stackoverflow.com/a/51286749/7346633
if dataclasses.is_dataclass(o):
@@ -66,7 +62,24 @@ class EnhancedJSONEncoder(json.JSONEncoder):
if isinstance(o, Path):
return str(o)
return super().default(o)
# Support for byte arrays (encode as base64 string)
if isinstance(o, bytes):
return base64.b64encode(o).decode()
# Enums
if isinstance(o, Enum):
return o.name
return None
class EnhancedJSONEncoder(json.JSONEncoder):
"""
An improvement to the json.JSONEncoder class, which supports:
encoding for dataclasses, encoding for datetime, and sets
"""
def default(self, o: object) -> object:
return infer(o) or super().default(o)
class ForceJSONEcoder(EnhancedJSONEncoder):
@@ -74,14 +87,17 @@ class ForceJSONEcoder(EnhancedJSONEncoder):
A json encoder that can serialize almost everything (including custom classes, byte arrays)
"""
def default(self, o: object) -> object:
infer_result = infer(o)
if infer_result:
return infer_result
# Support for byte arrays (encode as base64 string)
if isinstance(o, bytes):
return base64.b64encode(o).decode()
# Support EnumType
if isinstance(o, EnumType):
return {i.name: i.value for i in o}
# Support for custom classes (get dict values)
if hasattr(o, '__dict__'):
return vars(o)
if hasattr(o, '__dict__') and not inspect.isclass(o):
return dict(vars(o))
return super().default(o)