import dataclasses import datetime import decimal import json import uuid from typing import Any class JSONEncoder(json.JSONEncoder): def default(self, o: Any) -> Any: if isinstance(o, datetime.datetime | datetime.date | datetime.time): return o.isoformat() elif isinstance(o, datetime.timedelta): return str(o.total_seconds()) elif isinstance(o, decimal.Decimal): # Serializers will coerce decimals to strings by default. return str(o) elif isinstance(o, uuid.UUID): return str(o) elif isinstance(o, bytes): # Best-effort for binary blobs. See #4187. return o.decode() elif dataclasses and dataclasses.is_dataclass(o): return dataclasses.asdict(o) # type: ignore[arg-type] return super().default(o) class SafeJSONEncoder(JSONEncoder): def default(self, o: Any) -> Any: try: return super().default(o) except TypeError: return str(o)