Source code for xsdata.formats.converters

from dataclasses import is_dataclass
from decimal import Decimal
from enum import Enum
from typing import Any
from typing import Callable
from typing import Dict
from typing import List
from typing import Type


[docs]def sort_types(types: List[Type]): in_order = (bool, int, str, float, Decimal) sorted_types = [] for ordered in in_order: if ordered in types: types.remove(ordered) sorted_types.append(ordered) types.extend(sorted_types) return types
[docs]def to_python(types: List[Type], value: Any, in_order=True) -> Any: if not isinstance(value, str): return value if not in_order and len(types) > 1: types = sort_types(list(types)) for clazz in types: try: if clazz.__name__ in func_map: return func_map[clazz.__name__](value) else: return to_class(clazz, value) except ValueError: pass return value
[docs]def to_class(clazz: Any, value: Any) -> Any: try: if issubclass(clazz, Enum): return to_enum(clazz, value) elif is_dataclass(clazz): return clazz(value) except KeyError: raise ValueError(f"Unhandled class type {clazz.__name__}")
[docs]def to_enum(clazz: Type[Enum], value: Any) -> Enum: enumeration = next(enumeration for enumeration in clazz) return clazz(type(enumeration.value)(value))
[docs]def to_bool(value: Any) -> bool: if value in ("true", "1"): return True if value in ("false", "0"): return False raise ValueError(f"Invalid bool literal '{value}'")
[docs]def to_xml(value: Any) -> str: if isinstance(value, bool): return "true" if value else "false" if isinstance(value, Enum): return str(value.value) return str(value)
func_map: Dict[str, Callable] = { "str": str, "int": int, "float": float, "bool": to_bool, "Decimal": Decimal, }