File size: 1,353 Bytes
5df544f
70f3ca7
5df544f
 
 
 
 
 
 
 
 
 
 
 
70f3ca7
 
5df544f
 
 
 
 
e0d6ecb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import math
from decimal import Decimal
from typing import Any

def clean_nans(obj: Any) -> Any:
    """
    Recursive utility to replace NaN, Infinity, and -Infinity with None
    to ensure JSON compatibility.
    Standards Moez Elbey: Missing data => null/None.
    """
    if isinstance(obj, float):
        if math.isnan(obj) or math.isinf(obj):
            return None
        return obj
    elif isinstance(obj, Decimal):
        return float(obj)
    elif isinstance(obj, dict):
        return {k: clean_nans(v) for k, v in obj.items()}
    elif isinstance(obj, list):
        return [clean_nans(v) for v in obj]
    return obj

def safe_float(val: Any, default: float = 0.0) -> float:
    """Safely convert any value to float."""
    try:
        if val is None or (isinstance(val, float) and math.isnan(val)):
            return default
        return float(val)
    except (ValueError, TypeError):
        return default

def safe_int(val: Any, default: int = 0) -> int:
    """Safely convert any value to int."""
    try:
        if val is None or (isinstance(val, float) and math.isnan(val)):
            return default
        return int(float(val))
    except (ValueError, TypeError):
        return default

def safe_list(val: Any) -> list:
    """Ensure value is a list."""
    if isinstance(val, list):
        return val
    return []