|
1 | 1 | import json |
2 | 2 | import re |
| 3 | +from enum import Enum |
3 | 4 | from typing import List, Any, Dict, Union |
4 | 5 | from dataclasses import is_dataclass, asdict |
5 | 6 | from datetime import date, datetime |
@@ -302,6 +303,9 @@ def json_safe_stringify(o): |
302 | 303 | return o.isoformat() |
303 | 304 | return str(o) # last resort |
304 | 305 |
|
| 306 | +def is_json_primitive(value: Any) -> bool: |
| 307 | + return isinstance(value, (str, int, float, bool)) or value is None |
| 308 | + |
305 | 309 | def make_json_safe(value: Any) -> Any: |
306 | 310 | """ |
307 | 311 | Recursively convert a value into a JSON-serializable structure. |
@@ -333,8 +337,18 @@ def make_json_safe(value: Any) -> Any: |
333 | 337 | if isinstance(value, (list, tuple)): |
334 | 338 | return [make_json_safe(sub_value) for sub_value in value] |
335 | 339 |
|
| 340 | + if isinstance(value, Enum): |
| 341 | + enum_value = value.value |
| 342 | + if is_json_primitive(enum_value): |
| 343 | + return enum_value |
| 344 | + return { |
| 345 | + "__type__": type(value).__name__, |
| 346 | + "name": value.name, |
| 347 | + "value": make_json_safe(enum_value), |
| 348 | + } |
| 349 | + |
336 | 350 | # Already JSON safe |
337 | | - if isinstance(value, (str, int, float, bool)) or value is None: |
| 351 | + if is_json_primitive(value): |
338 | 352 | return value |
339 | 353 |
|
340 | 354 | # Arbitrary object: try __dict__ first, fallback to repr |
|
0 commit comments