from typing import Union


def aslist(i, argname: Union[str, None], allowed_types=list):
    """
    Converts iterables (except strings) into a list.

    :param argname:
        If string, it's used in the exception raised when `i` not an iterable.
        If `None`, wraps non-iterables in a single-item list.
    """
    if not i:
        return i if isinstance(i, allowed_types) else []

    if isinstance(i, str):
        i = [i]
    elif not isinstance(i, allowed_types):
        try:
            i = list(i)
        except Exception as ex:
            if argname is None:
                return [i]
            raise ValueError(f"Cannot list-ize {argname}({i!r}) due to: {ex}") from None

    return i