r"""
    Args:
        varied_dict (dict):  parameters to vary with possible variations
        constraint_func (func): function to restirct parameter variations
        slice_dict (dict):  dict of slices for each param of valid possible values
        defaultslice (slice): default slice used if slice is not specified in slice_dict

    Returns:
        tuple: (cfgdict_list, cfglbl_list)

    CommandLine:
        python -m utool.util_gridsearch --test-make_constrained_cfg_and_lbl_list

    Example:
        >>> # DISABLE_DOCTEST
        >>> from utool.util_gridsearch import *  # NOQA
        >>> # build test data
        >>> varied_dict = {
        ...     'p': [.1, .3, 1.0, 2.0],
        ...     'dcvs_clip_max': [.1, .2, .5],
        ...     'K': [3, 5],
        ... }
        >>> constraint_func = None
        >>> # execute function
        >>> (cfgdict_list, cfglbl_list) = make_constrained_cfg_and_lbl_list(varied_dict, constraint_func)
        >>> # verify results
        >>> result = six.text_type((cfgdict_list, cfglbl_list))
        >>> print(result)

def make_constrained_cfg_and_lbl_list(varied_dict, constraint_func=None,
                                      slice_dict=None,
                                      defaultslice=slice(0, 1)):
    r"""
    Args:
        varied_dict (dict):  parameters to vary with possible variations
        constraint_func (func): function to restirct parameter variations
        slice_dict (dict):  dict of slices for each param of valid possible values
        defaultslice (slice): default slice used if slice is not specified in slice_dict

    Returns:
        tuple: (cfgdict_list, cfglbl_list)

    CommandLine:
        python -m utool.util_gridsearch --test-make_constrained_cfg_and_lbl_list

    Example:
        >>> # DISABLE_DOCTEST
        >>> from utool.util_gridsearch import *  # NOQA
        >>> # build test data
        >>> varied_dict = {
        ...     'p': [.1, .3, 1.0, 2.0],
        ...     'dcvs_clip_max': [.1, .2, .5],
        ...     'K': [3, 5],
        ... }
        >>> constraint_func = None
        >>> # execute function
        >>> (cfgdict_list, cfglbl_list) = make_constrained_cfg_and_lbl_list(varied_dict, constraint_func)
        >>> # verify results
        >>> result = six.text_type((cfgdict_list, cfglbl_list))
        >>> print(result)
    """
    # Restrict via slices
    if slice_dict is None:
        varied_dict_ = varied_dict
    else:
        varied_dict_ = {
            key: val[slice_dict.get(key, defaultslice)]
            for key, val in six.iteritems(varied_dict)
        }
    # Enumerate all combinations
    cfgdict_list_ = util_dict.all_dict_combinations(varied_dict_)
    if constraint_func is not None:
        # Remove invalid combinations
        cfgdict_list = constrain_cfgdict_list(cfgdict_list_, constraint_func)
    else:
        cfgdict_list = cfgdict_list_
    # Get labels and return
    cfglbl_list = make_cfglbls(cfgdict_list, varied_dict)
    return cfgdict_list, cfglbl_list