Source code for baybe.utils.conversion

"""Conversion utilities."""

from collections.abc import Sequence
from fractions import Fraction
from typing import Any, TypeVar

from attrs import Attribute

_T = TypeVar("_T")


[docs] def fraction_to_float(value: str | float | Fraction, /) -> float: """Convert the provided input representing a fraction into a float. Args: value: The input to be converted. Returns: The float representation of the given input. Raises: ValueError: If the input was provided as string but could not be interpreted as fraction. """ if isinstance(value, str): try: value = Fraction(value) except ValueError as err: raise ValueError( f"The provided input '{value}' could not be interpreted as a fraction." ) from err return float(value)
[docs] def nonstring_to_tuple(x: Sequence[_T], self: type, field: Attribute) -> tuple[_T, ...]: """Convert a sequence to tuple but raise an exception for string input.""" if isinstance(x, str): raise ValueError( f"Argument passed to '{field.alias}' of class '{self.__class__.__name__}' " f"must be a sequence but cannot be a string." ) return tuple(x)
def _indent(text: str, amount: int = 3, ch: str = " ") -> str: """Indent a given text by a certain amount.""" padding = amount * ch return "".join(padding + line for line in text.splitlines(keepends=True))
[docs] def to_string(header: str, *fields: Any, single_line: bool = False) -> str: """Create a nested string representation. Args: header: The header, typically the name of a class. *fields: Fields to be printed with an indentation. single_line: If ``True``, print the representation on a single line. Only applicable when given a single field. Raises: ValueError: If ``single_line`` is ``True`` but ``fields`` contains more than one element. Returns: The string representation with indented fields. """ if single_line: if len(fields) > 1: raise ValueError( "``single_line`` is only applicable when given a single field." ) # Since single line headers look ugly without a ":", we add it manually header = header if header.endswith(":") else header + ":" return f"{header} {str(fields[0])}" return "\n".join([header] + [_indent(str(f)) for f in fields])