def _check_var(
    var,
    varname,
    types=None,
    default=None,
    allowed=None,
    excluded=None,
):
    """ Check a variable, with options

    - check is instance of any types
    - check belongs to list of allowed values
    - check does not belong to list of excluded values

    if None:
        - set to default if provided
        - set to allowed value if only has 1 element

    Print proper error message if necessary, return the variable itself

    """

    # set to default
    if var is None:
        var = default
    if var is None and allowed is not None and len(allowed) == 1:
        if not isinstance(allowed, list):
            allowed = list(allowed)
        var = allowed[0]

    # check type
    if types is not None:
        if not isinstance(var, types):
            msg = (
                f"Arg {varname} must be of type {types}!\n"
                f"Provided: {type(var)}"
            )
            raise Exception(msg)

    # check if allowed
    if allowed is not None:
        if var not in allowed:
            msg = (
                f"Arg {varname} must be in {allowed}!\n"
                f"Provided: {var}"
            )
            raise Exception(msg)

    # check if excluded
    if excluded is not None:
        if var in excluded:
            msg = (
                f"Arg {varname} must not be in {excluded}!\n"
                f"Provided: {var}"
            )
            raise Exception(msg)

    return var