from typing import Iterable


def as_str_list(arg, idx_names=None):
    """Convert various *arg* to list of str.

    Several types of arguments are handled:

    - :obj:`None`: returned as None.
    - class:`str`: returned as a length-1 list of str.
    - iterable of values: :class:`str` is called on each value.
    - :class:`dict`, with `idx_names`: the `idx_names` are used to look up values in the
      dict. The return value has the corresponding values in the same order.

    """
    if arg is None:
        return None
    elif idx_names is None:
        # arg must be iterable
        # NB narrower ABC Sequence does not work here; e.g. test_excel_io()
        #    fails via Scenario.add_set().
        if isinstance(arg, Iterable) and not isinstance(arg, str):
            return list(map(str, arg))
        else:
            return [str(arg)]
    else:
        return [str(arg[idx]) for idx in idx_names]