from typing import Mapping
from typing import Sequence


def apply_to_type(input_, input_type, func):
    """Apply a function on a object of `input_type` or mapping, or sequence of objects of `input_type`.
    """
    if isinstance(input_, input_type):
        return func(input_)
    if isinstance(input_, (str, bytes)):
        return input_
    if isinstance(input_, Mapping):
        return type(input_)({k: apply_to_type(sample, input_type, func) for k, sample in input_.items()})
    if isinstance(input_, tuple) and hasattr(input_, "_fields"):  # namedtuple
        return type(input_)(*(apply_to_type(sample, input_type, func) for sample in input_))
    if isinstance(input_, Sequence):
        return type(input_)([apply_to_type(sample, input_type, func) for sample in input_])
    raise TypeError(("input must contain {}, dicts or lists; found {}".format(input_type, type(input_))))