(value: V, hint: Type[H])
Cast a value into a given type hint

    If a value cannot be cast then the original value will be returned
    and a warning emitted
Cast a value into a given type hint
Cast a value into a given type hint
def cast_to_hint(value: V, hint: Type[H]) -> Union[V, H]:
    """Cast a value into a given type hint

    If a value cannot be cast then the original value will be returned
    and a warning emitted
    """
    # pylint: disable=too-many-return-statements
    if value is None:
        return None
    elif hint in (Any, ...):
        return value

    optional_hint = is_optional(hint)
    if optional_hint and value is not None:
        hint = optional_hint

    hint_type, hint_args = parse_hint(hint)
    is_class = inspect.isclass(hint_type)

    if hint_type == Union:
        # We don't attempt to deal with unions for now
        return value
    elif hint == inspect.Parameter.empty:
        # Empty annotation
        return value
    elif isinstance_safe(value, hint):
        # Already correct type
        return value
    elif hasattr(hint, "__from_bus__") and isinstance_safe(value, Mapping):
        # Hint supports custom deserializing. Do the best we can
        # with casting our dict-ish value onto the classes annotation ,
        # then pass the resulting dict to __from_bus__ to deal with as it wishes.
        return _mapping_to_instance(
            mapping=value,
            destination_type=hint,
            instantiator=hint.__from_bus__,
            expand_kwargs=False,
        )
    elif hasattr(hint, "__from_bus__"):
        # Hint supports custom deserializing. This is a non-mapping value,
        # so just pass it do __from_bus__ to do with as it wishes
        return hint.__from_bus__(value)
    elif issubclass_safe(hint, bytes):
        return b64decode(value.encode("utf8"))
    elif type_is_namedtuple(hint) and isinstance_safe(value, Mapping):
        return _mapping_to_instance(mapping=value, destination_type=hint)
    elif type_is_dataclass(hint) and isinstance_safe(value, Mapping):
        return _mapping_to_instance(mapping=value, destination_type=hint)
    elif is_class and issubclass_safe(hint_type, datetime.datetime) and isinstance_safe(value, str):
        # Datetime as a string
        return iso_datetime_parser(value)
    elif is_class and issubclass_safe(hint_type, datetime.date) and isinstance_safe(value, str):
        # Date as a string
        return cast_or_warning(lambda v: iso_datetime_parser(v).date(), value)
    elif is_class and issubclass_safe(hint_type, list):
        # Lists
        if hint_args and hasattr(value, "__iter__"):
            value = [cast_to_hint(i, hint_args[0]) for i in value]
        return cast_or_warning(list, value)
    elif is_class and issubclass_safe(hint_type, tuple):
        # Tuples
        if hint_args and hasattr(value, "__iter__"):
            value = [cast_to_hint(h, hint_args[i]) for i, h in enumerate(value)]
        return cast_or_warning(tuple, value)
    elif is_class and issubclass_safe(hint_type, set):
        # Sets
        if hint_args and hasattr(value, "__iter__"):
            value = [cast_to_hint(i, hint_args[0]) for i in value]
        return cast_or_warning(set, value)
    elif (
        inspect.isclass(hint)
        and hasattr(hint, "__annotations__")
        and not issubclass_safe(hint_type, Enum)
    ):
        logger.warning(
            f"Cannot cast to arbitrary class {hint}, using un-casted value. "
            "If you want to receive custom objects you can 1) "
            "use a NamedTuple, 2) use a dataclass, or 3) specify the "
            "__from_bus__() and __to_bus__() magic methods."
        )
        return value
    else:
        return cast_or_warning(hint, value)
def cast_to_hint ( value : V , hint : Type [ H ] ) -> Union [ V , H ] : # pylint: disable=too-many-return-statements if value is None : return None elif hint in ( Any , ... ) : return value optional_hint = is_optional ( hint ) if optional_hint and value is not None : hint = optional_hint hint_type , hint_args = parse_hint ( hint ) is_class = inspect . isclass ( hint_type ) if hint_type == Union : # We don't attempt to deal with unions for now return value elif hint == inspect . Parameter . empty : # Empty annotation return value elif isinstance_safe ( value , hint ) : # Already correct type return value elif hasattr ( hint , "__from_bus__" ) and isinstance_safe ( value , Mapping ) : # Hint supports custom deserializing. Do the best we can # with casting our dict-ish value onto the classes annotation , # then pass the resulting dict to __from_bus__ to deal with as it wishes. return _mapping_to_instance ( mapping = value , destination_type = hint , instantiator = hint . __from_bus__ , expand_kwargs = False , ) elif hasattr ( hint , "__from_bus__" ) : # Hint supports custom deserializing. This is a non-mapping value, # so just pass it do __from_bus__ to do with as it wishes return hint . __from_bus__ ( value ) elif issubclass_safe ( hint , bytes ) : return b64decode ( value . encode ( "utf8" ) ) elif type_is_namedtuple ( hint ) and isinstance_safe ( value , Mapping ) : return _mapping_to_instance ( mapping = value , destination_type = hint ) elif type_is_dataclass ( hint ) and isinstance_safe ( value , Mapping ) : return _mapping_to_instance ( mapping = value , destination_type = hint ) elif is_class and issubclass_safe ( hint_type , datetime . datetime ) and isinstance_safe ( value , str ) : # Datetime as a string return iso_datetime_parser ( value ) elif is_class and issubclass_safe ( hint_type , datetime . date ) and isinstance_safe ( value , str ) : # Date as a string return cast_or_warning ( lambda v : iso_datetime_parser ( v ) . date ( ) , value ) elif is_class and issubclass_safe ( hint_type , list ) : # Lists if hint_args and hasattr ( value , "__iter__" ) : value = [ cast_to_hint ( i , hint_args [ 0 ] ) for i in value ] return cast_or_warning ( list , value ) elif is_class and issubclass_safe ( hint_type , tuple ) : # Tuples if hint_args and hasattr ( value , "__iter__" ) : value = [ cast_to_hint ( h , hint_args [ i ] ) for i , h in enumerate ( value ) ] return cast_or_warning ( tuple , value ) elif is_class and issubclass_safe ( hint_type , set ) : # Sets if hint_args and hasattr ( value , "__iter__" ) : value = [ cast_to_hint ( i , hint_args [ 0 ] ) for i in value ] return cast_or_warning ( set , value ) elif ( inspect . isclass ( hint ) and hasattr ( hint , "__annotations__" ) and not issubclass_safe ( hint_type , Enum ) ) : logger . warning ( f"Cannot cast to arbitrary class {hint}, using un-casted value. " "If you want to receive custom objects you can 1) " "use a NamedTuple, 2) use a dataclass, or 3) specify the " "__from_bus__() and __to_bus__() magic methods." ) return value else : return cast_or_warning ( hint , value )