def parse_index(arg, min_val=None, max_val=None):
    """Parses indices.

    If the input is a list or tuple, this function has no effect.

    If the input is a string, it can be either a comma separated list of numbers
    `1, 3, 5`, or a dash separated range `3 - 10`. Spaces in the string will be
    ignored.

    Args:
        arg: The input argument to parse indices from.
        min_val: If not `None`, this function will check that all indices are
            equal to or larger than this value. (default: None)
        max_val: If not `None`, this function will check that all indices are
            equal to or smaller than this field. (default: None)

    Returns:
        A list of integers.

    Raises:
        ValueError: If the input is invalid, i.e., neither a list or tuple, nor
            a string.
    """
    if arg is None or arg == '':
        indices = []
    elif isinstance(arg, int):
        indices = [arg]
    elif isinstance(arg, (list, tuple)):
        indices = list(arg)
    elif isinstance(arg, str):
        indices = []
        if arg.lower() not in ['none', 'null']:
            splits = arg.replace(' ', '').split(',')
            for split in splits:
                numbers = list(map(int, split.split('-')))
                if len(numbers) == 1:
                    indices.append(numbers[0])
                elif len(numbers) == 2:
                    indices.extend(list(range(numbers[0], numbers[1] + 1)))
    else:
        raise ValueError(f'Invalid type of input: `{type(arg)}`!')

    assert isinstance(indices, list)
    indices = sorted(list(set(indices)))
    for idx in indices:
        assert isinstance(idx, int)
        if min_val is not None:
            assert idx >= min_val, f'{idx} is smaller than min val `{min_val}`!'
        if max_val is not None:
            assert idx <= max_val, f'{idx} is larger than max val `{max_val}`!'

    return indices