tokencrawler/.venv/lib/python3.9/site-packages/apischema/deserialization/coercion.py
2022-03-17 22:16:30 +01:00

55 lines
1.4 KiB
Python

from typing import Any, Callable, Dict, Type, TypeVar, Union
from apischema.json_schema.types import bad_type
from apischema.types import NoneType
T = TypeVar("T")
Coercer = Callable[[Type[T], Any], T]
_bool_pairs = (
("0", "1"),
("f", "t"),
("n", "y"),
("no", "yes"),
("false", "true"),
("off", "on"),
("ko", "ok"),
)
STR_TO_BOOL: Dict[str, bool] = {}
for false, true in _bool_pairs:
for s, value in ((false, False), (true, True)):
STR_TO_BOOL[s.lower()] = value
STR_NONE_VALUES = {""}
def coerce(cls: Type[T], data: Any) -> T:
if cls is NoneType:
if data is None or data in STR_NONE_VALUES:
return None # type: ignore
else:
raise bad_type(data, cls)
elif isinstance(data, cls):
return data
elif cls is bool:
if isinstance(data, str):
return STR_TO_BOOL[data.lower()] # type: ignore
elif isinstance(data, int):
return bool(data) # type: ignore
else:
raise bad_type(data, cls)
elif cls in (int, float):
try:
return cls(data) # type: ignore
except ValueError:
raise bad_type(data, cls)
elif cls is str:
if isinstance(data, (int, float)) and not isinstance(data, bool):
return str(data) # type: ignore
else:
raise bad_type(data, cls)
else:
raise bad_type(data, cls)
Coerce = Union[bool, Coercer]