Repository: psf/black
File: src/black/__init__.py (Python)

Code before:
        raise click.BadOptionUsage(
            "extend-exclude", "Config key extend-exclude must be a string"
        )

    line_ranges = config.get("line_ranges")
    if line_ranges is not None:
        raise click.BadOptionUsage(
            "line-ranges", "Cannot use line-ranges in the pyproject.toml file."
        )

    default_map: Dict[str, Any] = {}
    if ctx.default_map:
        default_map.update(ctx.default_map)
    default_map.update(config)

    ctx.default_map = default_map
    return value


def spellcheck_pyproject_toml_keys(
    ctx: click.Context, config_keys: List[str], config_file_path: str
) -> None:
    available_config_options = {param.name for param in ctx.command.params}
    for key in config_keys:
        if key not in available_config_options:
            raise InvalidConfigKey(f"Invalid key {key} in {config_file_path}")


def target_version_option_callback(
    c: click.Context, p: Union[click.Option, click.Parameter], v: Tuple[str, ...]
) -> List[TargetVersion]:
    """Compute the target versions from a --target-version flag.

    This is its own function because mypy couldn't infer the type correctly
    when it was a lambda, causing mypyc trouble.
    """
    return [TargetVersion[val.upper()] for val in v]


def re_compile_maybe_verbose(regex: str) -> Pattern[str]:
    """Compile a regular expression string in `regex`.

    If it contains newlines, use verbose mode.
    """
    if "\n" in regex:
        regex = "(?x)" + regex
    compiled: Pattern[str] = re.compile(regex)
    return compiled


def validate_regex(

Review comment (bug):
If there are multiple invalid keys, could you make the error message list them all at once? That makes for a better debugging experience, since otherwise if you have N invalid keys you have to run Black N times to see them all.

Code after:
    line_ranges = config.get("line_ranges")
    if line_ranges is not None:
        raise click.BadOptionUsage(
            "line-ranges", "Cannot use line-ranges in the pyproject.toml file."
        )

    default_map: Dict[str, Any] = {}
    if ctx.default_map:
        default_map.update(ctx.default_map)
    default_map.update(config)

    ctx.default_map = default_map
    return value


def spellcheck_pyproject_toml_keys(
    ctx: click.Context, config_keys: List[str], config_file_path: str
) -> None:
    invalid_keys: List[str] = []
    available_config_options = {param.name for param in ctx.command.params}
    for key in config_keys:
        if key not in available_config_options:
            invalid_keys.append(key)
    if invalid_keys:
        keys_str = ", ".join(map(repr, invalid_keys))
        out(
            f"Invalid config keys detected: {keys_str} (in {config_file_path})",
            fg="red",
        )


def target_version_option_callback(
    c: click.Context, p: Union[click.Option, click.Parameter], v: Tuple[str, ...]
) -> List[TargetVersion]:
    """Compute the target versions from a --target-version flag.

    This is its own function because mypy couldn't infer the type correctly
    when it was a lambda, causing mypyc trouble.
    """
    return [TargetVersion[val.upper()] for val in v]


def re_compile_maybe_verbose(regex: str) -> Pattern[str]:
    """Compile a regular expression string in `regex`.

    If it contains newlines, use verbose mode.
    """
    if "\n" in regex:
        regex = "(?x)" + regex
    compiled: Pattern[str] = re.compile(regex)
    return compiled