Set up global configuration for tests and noninteractive tools.

    `modules` is an iterable of
    :class:`yakonfig.Configurable` objects, or anything
    equivalently typed.  This function iterates through those objects
    to produce a default configuration, reads `yaml` as though it were
    the configuration file, and fills in any values from `params` as
    though they were command-line arguments.  The resulting
    configuration is set as the global configuration.

    :param modules: modules or Configurable instances to use
    :type modules: iterable of :class:`~yakonfig.Configurable`
    :param dict params: dictionary of command-line argument key to values
    :param str yaml: global configuration file
    :param str filename: location of global configuration file
    :param dict config: global configuration object
    :param bool validate: check configuration after creating
    :return: the new global configuration
    :returntype: dict

def set_default_config(modules, params=None, yaml=None, filename=None,
                       config=None, validate=True):
    """Set up global configuration for tests and noninteractive tools.

    `modules` is an iterable of
    :class:`yakonfig.Configurable` objects, or anything
    equivalently typed.  This function iterates through those objects
    to produce a default configuration, reads `yaml` as though it were
    the configuration file, and fills in any values from `params` as
    though they were command-line arguments.  The resulting
    configuration is set as the global configuration.

    :param modules: modules or Configurable instances to use
    :type modules: iterable of :class:`~yakonfig.Configurable`
    :param dict params: dictionary of command-line argument key to values
    :param str yaml: global configuration file
    :param str filename: location of global configuration file
    :param dict config: global configuration object
    :param bool validate: check configuration after creating
    :return: the new global configuration
    :returntype: dict

    """
    if params is None:
        params = {}

    # Get the configuration from the file, or from params['config']
    file_config = {}
    if yaml is None and filename is None and config is None:
        if 'config' in params and params['config'] is not None:
            filename = params['config']
    if yaml is not None or filename is not None or config is not None:
        if yaml is not None:
            file_config = yaml_mod.load(StringIO(yaml))
        elif filename is not None:
            with open(filename, 'r') as f:
                file_config = yaml_mod.load(f)
        elif config is not None:
            file_config = config

    # First pass: set up to call replace_config()
    # Assemble the configuration from defaults + file + arguments
    base_config = copy.deepcopy(file_config)
    create_config_tree(base_config, modules)
    fill_in_arguments(base_config, modules, params)
    default_config = assemble_default_config(modules)
    base_config = overlay_config(default_config, base_config)

    # Replace the modules list (accommodate external modules)
    def replace_module(config, m):
        name = getattr(m, 'config_name')
        c = config.get(name, {})
        if hasattr(m, 'replace_config'):
            return getattr(m, 'replace_config')(c, name)
        return m
    modules = [replace_module(base_config, m) for m in modules]

    # Reassemble the configuration again, this time reaching out to
    # the environment
    base_config = file_config
    create_config_tree(base_config, modules)
    fill_in_arguments(base_config, modules, params)
    do_config_discovery(base_config, modules)
    default_config = assemble_default_config(modules)
    base_config = overlay_config(default_config, file_config)
    fill_in_arguments(base_config, modules, params)

    # Validate the configuration
    if validate and len(modules) > 0:
        mod = modules[-1]
        checker = getattr(mod, 'check_config', None)
        if checker is not None:
            with _temporary_config():
                set_global_config(base_config)
                checker(base_config[mod.config_name], mod.config_name)

    # All done, normalize and set the global configuration
    normalize_config(base_config, modules)
    set_global_config(base_config)
    return base_config