From 5999d302e0cf6c5adefe97fab66c80120f38ed52 Mon Sep 17 00:00:00 2001 From: Albert Tugushev Date: Sun, 16 Jul 2023 23:16:52 +0200 Subject: [PATCH] Refactor multi value options validation --- piptools/utils.py | 25 +++++-------------------- tests/test_utils.py | 24 ++++++++++++++---------- 2 files changed, 19 insertions(+), 30 deletions(-) diff --git a/piptools/utils.py b/piptools/utils.py index 68a46f51d..b6b663b9e 100644 --- a/piptools/utils.py +++ b/piptools/utils.py @@ -608,11 +608,14 @@ def _validate_config( # Validate invalid values param = cli_params[key] try: - param.type.convert(value=value, param=param, ctx=click_context) + param.type_cast_value(value=value, ctx=click_context) except Exception as e: raise click.BadOptionUsage( option_name=key, - message=f"Invalid value for config key {key!r}: {value!r}.", + message=( + f"Invalid value for config key {key!r}: {value!r}.{os.linesep}" + f"Details: {e}" + ), ctx=click_context, ) from e @@ -670,17 +673,6 @@ def get_click_dest_for_option(option_name: str) -> str: return option_name -# Ensure that any default overrides for these click options are lists, supporting multiple values -MULTIPLE_VALUE_OPTIONS = [ - "extras", - "upgrade_packages", - "unsafe_package", - "find_links", - "extra_index_url", - "trusted_host", -] - - def parse_config_file(config_file: Path) -> dict[str, Any]: try: config = tomllib.loads(config_file.read_text(encoding="utf-8")) @@ -700,13 +692,6 @@ def parse_config_file(config_file: Path) -> dict[str, Any]: piptools_config = { get_click_dest_for_option(k): v for k, v in piptools_config.items() } - # Any option with multiple values needs to be a list in the pyproject.toml - for mv_option in MULTIPLE_VALUE_OPTIONS: - if not isinstance(piptools_config.get(mv_option), (list, type(None))): - original_option = mv_option.replace("_", "-") - raise click.BadOptionUsage( - original_option, f"Config key '{original_option}' must be a list" - ) return piptools_config diff --git a/tests/test_utils.py b/tests/test_utils.py index f06a42100..dd5fdbfa1 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -623,21 +623,25 @@ def test_callback_config_file_defaults(pyproject_param, new_default, make_config @pytest.mark.parametrize( - "mv_option", + ("param", "value"), ( - "extra", - "upgrade-package", - "unsafe-package", - "find-links", - "extra-index-url", - "trusted-host", + ("extra", "not-a-list"), + ("upgrade_package", "not-a-list"), + ("unsafe_package", "not-a-list"), + ("find_links", "not-a-list"), + ("extra_index_url", "not-a-list"), + ("trusted_host", "not-a-list"), + ("annotate", "not-a-bool"), + ("max_rounds", "not-an-int"), ), ) -def test_callback_config_file_defaults_multi_value_options(mv_option, make_config_file): - config_file = make_config_file(mv_option, "not-a-list") +def test_callback_config_file_defaults_multi_validate_value( + param, value, make_config_file +): + config_file = make_config_file(param, value) ctx = Context(compile_cli) ctx.params["src_files"] = (str(config_file),) - with pytest.raises(BadOptionUsage, match="must be a list"): + with pytest.raises(BadOptionUsage, match="Invalid value for config key"): override_defaults_from_config_file(ctx, "config", None)