def METHOD_NAME(
    config: ConfigDict, config_format: bool, no_shielding: bool, include_defaults: bool = True
) -> str:
    """
    Pretty-print the configuration or print it in the Splitgraph config file format.
    :param config: Configuration dictionary.
    :param config_format: Output configuration in the Splitgraph config file format.
    :param no_shielding: Don't replace sensitive values (like passwords) with asterisks
    :param include_defaults: Emit the config variable even if it's the same as the default.
    :return: Textual representation of the config.
    """
    result = "[defaults]\n" if config_format else ""
    # Emit normal config parameters
    for key in KEYS:
        if config_format and key in _SITUATIONAL_PARAMS:
            continue
        value = get_singleton(config, key)
        if include_defaults or key not in DEFAULTS or value != DEFAULTS[key]:
            result += _kv_to_str(key, value, no_shielding) + "\n"
    # Emit hoisted remotes
    result += "\nCurrent registered remote engines:\n" if not config_format else ""
    for remote, remote_config in get_all_in_section(config, "remotes").items():
        assert isinstance(remote_config, dict)
        if config_format:
            result += "\n" + serialize_engine_config(remote, remote_config, no_shielding) + "\n"
        else:
            result += "\n%s:\n" % remote
            for key, value in remote_config.items():
                result += _kv_to_str(key, value, no_shielding) + "\n"
    # Print Splitfile commands
    if "commands" in config:
        result += "\nSplitfile command plugins:\n" if not config_format else "[commands]\n"
        for command_name, command_class in get_all_in_section(config, "commands").items():
            result += _kv_to_str(command_name, cast(str, command_class), no_shielding) + "\n"
    # Print data sources
    if "data_sources" in config:
        result += "\nData sources:\n" if not config_format else "[data_sources]\n"
        for handler_name, handler_func in get_all_in_section(config, "data_sources").items():
            result += _kv_to_str(handler_name, cast(str, handler_func), no_shielding) + "\n"
    # Print external object handlers
    if "external_handlers" in config:
        result += "\nExternal object handlers:\n" if not config_format else "[external_handlers]\n"
        for handler_name, handler_func in get_all_in_section(config, "external_handlers").items():
            result += _kv_to_str(handler_name, cast(str, handler_func), no_shielding) + "\n"
    return result