Source code for typist._core

"""The typist package's catch-all module.

You should only add code to this module when you are unable to find ANY other
module to add it to.
"""

from __future__ import annotations

import datetime as dt
from enum import Enum
import json
from pathlib import Path
from typing import Any, List, NoReturn, Protocol, TypeVar, Union, get_args


Comp_T = TypeVar("Comp_T", bound="Comparable")

DateLike = Union[str, dt.date, dt.datetime]
PathLike = Union[str, Path]


[docs]class ToDictable(Protocol): """Any object with a to_dict() method."""
[docs] def to_dict(self) -> dict[str, Any]: """Converts this object to a dictionary."""
[docs]class Comparable(Protocol): """A type that can be compared and sorted.""" def __eq__(self, other: Any) -> bool: # noqa: D105 pass def __lt__(self: Comp_T, other: Comp_T) -> bool: # noqa: D105 pass def __gt__(self: Comp_T, other: Comp_T) -> bool: # noqa: D105 pass def __le__(self: Comp_T, other: Comp_T) -> bool: # noqa: D105 pass def __ge__(self: Comp_T, other: Comp_T) -> bool: # noqa: D105 pass
[docs]def assert_never(value: NoReturn) -> NoReturn: """ Raises an AssertionError. This function can be used to achieve exhaustiveness checking with mypy. REFERENCE: https://hakibenita.com/python-mypy-exhaustive-checking """ raise AssertionError(f"Unhandled value: {value} ({type(value).__name__})")
[docs]def literal_to_list( literal: Any, ) -> List[Union[None, bool, bytes, int, str, Enum]]: """ Convert a typing.Literal into a list. Examples: >>> from typing import Literal >>> literal_to_list(Literal['a', 'b', 'c']) ['a', 'b', 'c'] >>> literal_to_list(Literal['a', 'b', Literal['c', 'd', Literal['e']]]) ['a', 'b', 'c', 'd', 'e'] >>> literal_to_list(Literal['a', 'b', Literal[1, 2, Literal[None]]]) ['a', 'b', 1, 2, None] """ result = [] for arg in get_args(literal): if arg is None or isinstance(arg, (bool, bytes, int, str, Enum)): result.append(arg) else: result.extend(literal_to_list(arg)) return result
[docs]def is_jsonable(obj: Any) -> bool: """Check if an object can be serialized to JSON. Args: obj: The object we want to serialize to JSON. Returns: True iff ``obj`` is JSON serializable. Examples: >>> is_jsonable("hi") True >>> is_jsonable(123) True >>> is_jsonable({"sets", "cannot", "be", "serialized", "to", "json"}) False """ try: json.dumps(obj) return True except (TypeError, OverflowError): return False