(obj, **kwargs)
| 476 | |
| 477 | |
| 478 | def clean_to_json_compatible(obj, **kwargs): |
| 479 | # Try handling value as a scalar value that we have a conversion for. |
| 480 | # Return immediately if we know we've hit a primitive value |
| 481 | |
| 482 | # Bail out fast for simple scalar types |
| 483 | if isinstance(obj, (int, float, str)): |
| 484 | return obj |
| 485 | |
| 486 | if isinstance(obj, dict): |
| 487 | return {k: clean_to_json_compatible(v, **kwargs) for k, v in obj.items()} |
| 488 | elif isinstance(obj, (list, tuple)): |
| 489 | if obj: |
| 490 | # Must process list recursively even though it may be slow |
| 491 | return [clean_to_json_compatible(v, **kwargs) for v in obj] |
| 492 | |
| 493 | # unpack kwargs |
| 494 | numpy_allowed = kwargs.get("numpy_allowed", False) |
| 495 | datetime_allowed = kwargs.get("datetime_allowed", False) |
| 496 | |
| 497 | modules = kwargs.get("modules", {}) |
| 498 | sage_all = modules["sage_all"] |
| 499 | np = modules["np"] |
| 500 | pd = modules["pd"] |
| 501 | image = modules["image"] |
| 502 | |
| 503 | # Sage |
| 504 | if sage_all is not None: |
| 505 | if obj in sage_all.RR: |
| 506 | return float(obj) |
| 507 | elif obj in sage_all.ZZ: |
| 508 | return int(obj) |
| 509 | |
| 510 | # numpy |
| 511 | if np is not None: |
| 512 | if obj is np.ma.core.masked: |
| 513 | return float("nan") |
| 514 | elif isinstance(obj, np.ndarray): |
| 515 | if numpy_allowed and obj.dtype.kind in ("b", "i", "u", "f"): |
| 516 | return np.ascontiguousarray(obj) |
| 517 | elif obj.dtype.kind == "M": |
| 518 | # datetime64 array |
| 519 | return np.datetime_as_string(obj).tolist() |
| 520 | elif obj.dtype.kind == "U": |
| 521 | return obj.tolist() |
| 522 | elif obj.dtype.kind == "O": |
| 523 | # Treat object array as a lists, continue processing |
| 524 | obj = obj.tolist() |
| 525 | elif isinstance(obj, np.datetime64): |
| 526 | return str(obj) |
| 527 | |
| 528 | # pandas |
| 529 | if pd is not None: |
| 530 | if obj is pd.NaT or obj is pd.NA: |
| 531 | return None |
| 532 | elif isinstance(obj, (pd.Series, pd.DatetimeIndex)): |
| 533 | if numpy_allowed and obj.dtype.kind in ("b", "i", "u", "f"): |
| 534 | return np.ascontiguousarray(obj.values) |
| 535 | elif obj.dtype.kind == "M": |
no test coverage detected