Skip to content

bagof.converters.base

Base class for all converters.

Attributes

ConverterRegistry module-attribute

ConverterRegistry = dict[Hashable, Type['Converter']]

A registry of converters, mapping type hints to converter classes.

register_converter module-attribute

register_converter = Converter.register

Backward-compatible alias for Converter.register.

get_converter module-attribute

get_converter = Converter.get

Backward-compatible alias for Converter.get.

get_converter_class module-attribute

get_converter_class = Converter.get_class

Backward-compatible alias for Converter.get_class.

Classes

Converter

Converter(hint: Any = UNSET, compose: bool = False)

Bases: MagicHint[TO], Generic[TO, FROM]

Base class for magic converters.

Converters take a value and return a converted version of it. They are registered in a global registry and looked up by type hint.

Note

Failed conversions raise a ConversionError. Its concrete subclasses -- ValueConversionError (also a ValueError) and TypeConversionError (also a TypeError) -- inherit the matching builtin, so callers that already catch ValueError or TypeError still catch conversion failures.

Refining converters

A converter class may declare refines=True as a class keyword argument (stored as REFINES, and inherited by subclasses unless overridden):

class ToEnum(Converter[T, Any], register=enum.Enum, refines=True):
    ...

It has two effects:

  • Union preference. The converter turns a value that is already an instance of a wider union branch into its own, narrower type -- e.g. Union[MyStrEnum, str]("a") gives MyStrEnum.A. ToUnion only tries such converters on values that already match another branch; see its docstring.
  • Dispatch over mixed-in bases. For a class hint, the nearest base registered with a refining converter wins over nearer non-refining bases, so class E(str, Enum) dispatches to the enum converter rather than the str one. An exact registry key still wins, and so does a nearer registered base that is itself a subclass of the refining one (e.g. a custom converter registered for your own Enum base class, refining or not).

Parameters:

Name Type Description Default
hint Any

The type hint to use for this magic object. If not provided, the default hint for the class is used.

UNSET
compose bool

Whether to compose this converter with others, when they are found in Annotated metadata.

False

Attributes

REFINES class-attribute
REFINES: bool = False

Whether this converter refines values of a wider union branch. Set with the refines= class keyword argument.

Methods:

like
like(__reentrant: tuple = ()) -> Any

Return a type hint describing valid inputs for this converter.

Parameters:

Name Type Description Default
__reentrant tuple

Used internally to avoid infinite recursion.

()

Returns:

Type Description
Any

A type hint for valid input values.

__call__
__call__(value: FROM) -> TO

Convert the given value.

Parameters:

Name Type Description Default
value FROM

The value to convert.

required

Returns:

Type Description
TO

The converted value.

Raises:

Type Description
ConversionError

If the value cannot be converted.

error
error(value: Any, message: str | None = None, **kwargs: Any) -> ConversionError

Return a ConversionError with the given value and message.

type_error
type_error(value: Any, message: str | None = None) -> TypeConversionError

Return a TypeConversionError with the given value.

value_error
value_error(value: Any, message: str | None = None) -> ValueConversionError

Return a ValueConversionError with the given value.

register staticmethod
register(converter: Type[Converter], *hints: Unpack[tuple[Any, ...]], registry: ConverterRegistry = ...) -> Type[Converter]
register(*hints: Unpack[tuple[Any, ...]], registry: ConverterRegistry = ...) -> ClassDecorator

Register a converter class for one or more type hints.

Can be used as a decorator or called directly:

Example

@Converter.register(int)
class ToInt(Converter[int, str]):
    def __call__(self, value: str) -> int:
        return int(value)

Parameters:

Name Type Description Default
*hints Any

One or more type hints to register the converter class for.

A ForwardRef key registers the object it names lazily: nothing is imported, and the key is resolved once that object has been imported by someone else. The name is looked up first relative to the registering class's module (or the ref's module=), then as an absolute dotted path. Names imported only under if TYPE_CHECKING: do not exist at runtime, so use the real dotted path -- ForwardRef("dask.array.Array"), not an alias such as "da.Array" -- or ForwardRef("Array", module="dask.array").

()
registry ConverterRegistry

The registry to register the converter class in. Defaults to the global registry.

CONVERTERS
get staticmethod
get(hint: Any, registry: ConverterRegistry = CONVERTERS, fallback: Type[Converter] | None = UNSET) -> Converter | None

Get the best-matching converter for a given type hint.

Example

>>> from bagof.converters import get_converter
>>> convert = get_converter(list[int])
>>> convert(["1", "2", "3"])
[1, 2, 3]
>>> get_converter(dict[str, int])({"a": "1", "b": "2"})
{'a': 1, 'b': 2}

Parameters:

Name Type Description Default
hint Any

The type hint for which to get a converter.

required
registry ConverterRegistry

The registry to look up the converter in. Defaults to the global registry.

CONVERTERS
fallback Optional[Type[Converter]]

The fallback converter class to use if no matching converter is found. Defaults to Converter. Pass None explicitly to get None instead of a fallback.

UNSET

Returns:

Type Description
Optional[Converter]

The best-matching converter for the given type hint, or None if no matching converter is found and no fallback is provided.

get_class staticmethod
get_class(hint: Any, registry: ConverterRegistry = CONVERTERS, fallback: Type[Converter] | None = UNSET) -> Type[Converter] | None

Get the best-matching converter class for a given type hint.

Parameters:

Name Type Description Default
hint Any

The type hint for which to get a converter.

required
registry ConverterRegistry

The registry to look up the converter in. Defaults to the global registry.

CONVERTERS
fallback Optional[Type[Converter]]

The fallback converter class to use if no matching converter is found. Defaults to Converter. Pass None explicitly to get None instead of a fallback.

UNSET

Returns:

Type Description
Optional[Type[Converter]]

The best-matching converter class for the given type hint, or None if no matching converter is found and no fallback is provided.

Functions:

wrap_converter

wrap_converter(converter: Converter, TO: Any = UNSET, FROM: Any = UNSET) -> Callable

Wrap a converter so that it has the correct input and output annotations.

Parameters:

Name Type Description Default
converter Converter

The converter to wrap.

required
TO Any

The output type hint. Defaults to converter.hint.

UNSET
FROM Any

The input type hint. Defaults to converter.like().

UNSET

Returns:

Type Description
Callable

A callable that wraps converter, annotated with FROM as its parameter type and TO as its return type.