diff --git a/cibuildwheel/options.py b/cibuildwheel/options.py index 2345f18d..afac21d0 100644 --- a/cibuildwheel/options.py +++ b/cibuildwheel/options.py @@ -52,8 +52,8 @@ from cibuildwheel.typing import PLATFORMS, PlatformName from cibuildwheel.util import resources from cibuildwheel.util.helpers import ( format_safe, + parse_arbitrary_key_value_string, parse_key_value_string, - parse_kw_string, strtobool, unwrap, ) @@ -449,7 +449,7 @@ def parse_inherit(config: str | dict[str, str] | None) -> dict[str, InheritRule] return {} if isinstance(config, str): - parsed = parse_kw_string(config, default_kw_value="append") + parsed = parse_arbitrary_key_value_string(config, default_value="append") inherit_dict = {k: "".join(v) for k, v in parsed.items()} elif isinstance(config, dict): inherit_dict = config @@ -874,7 +874,7 @@ class Options: if xbuild_tools == ["\u0000"]: xbuild_tools = None - xbuild_files = parse_kw_string( + xbuild_files = parse_arbitrary_key_value_string( self.reader.get( "xbuild-files", option_format=ShlexTableFormat(sep="; ", pair_sep=":", allow_merge=False), diff --git a/cibuildwheel/util/helpers.py b/cibuildwheel/util/helpers.py index 659df935..1121c724 100644 --- a/cibuildwheel/util/helpers.py +++ b/cibuildwheel/util/helpers.py @@ -147,7 +147,9 @@ def parse_key_value_string( return dict(result) -def parse_kw_string(kw_string: str, default_kw_value: str | None = None) -> dict[str, list[str]]: +def parse_arbitrary_key_value_string( + key_value_string: str, default_value: str | None = None +) -> dict[str, list[str]]: """ Parses a string like @@ -159,9 +161,9 @@ def parse_kw_string(kw_string: str, default_kw_value: str | None = None) -> dict No positional arguments are allowed. Words without a colon attached are interpreted as keys. Keys without a value will be assigned the - default_kw_value if provided, otherwise an empty list. + default_value if provided, otherwise throw an error. """ - shlexer = shlex.shlex(kw_string, posix=True, punctuation_chars=";") + shlexer = shlex.shlex(key_value_string, posix=True, punctuation_chars=";") shlexer.commenters = "" shlexer.whitespace_split = True parts = list(shlexer) @@ -180,12 +182,12 @@ def parse_kw_string(kw_string: str, default_kw_value: str | None = None) -> dict result[field_name] += values else: # no colon, so it's a key (or set of keys) without values - if default_kw_value is None: - msg = f"Failed to parse {kw_string!r}. No value specified for {field_name!r}. Expected ':' followed by a value." + if default_value is None: + msg = f"Failed to parse {key_value_string!r}. No value specified for {field_name!r}. Expected ':' followed by a value." raise ValueError(msg) for key in field: - result[key].append(default_kw_value) + result[key].append(default_value) return dict(result) diff --git a/unit_test/utils_test.py b/unit_test/utils_test.py index 189f4262..dc106d3c 100644 --- a/unit_test/utils_test.py +++ b/unit_test/utils_test.py @@ -11,8 +11,8 @@ from cibuildwheel.util.file import copy_test_sources, remove_on_error from cibuildwheel.util.helpers import ( FlexibleVersion, format_safe, + parse_arbitrary_key_value_string, parse_key_value_string, - parse_kw_string, prepare_command, unwrap, unwrap_preserving_paragraphs, @@ -220,53 +220,57 @@ def test_parse_key_value_string_unknown_name() -> None: parse_key_value_string("key: value") -def test_parse_kw_string_basic() -> None: - assert parse_kw_string("before-test: append; after-test: prepend") == { +def test_parse_arbitrary_key_value_string_basic() -> None: + assert parse_arbitrary_key_value_string("before-test: append; after-test: prepend") == { "before-test": ["append"], "after-test": ["prepend"], } -def test_parse_kw_string_multiple_values() -> None: - assert parse_kw_string("package1: some/header.h some/library.a; package2: other/header.h") == { +def test_parse_arbitrary_key_value_string_multiple_values() -> None: + assert parse_arbitrary_key_value_string( + "package1: some/header.h some/library.a; package2: other/header.h" + ) == { "package1": ["some/header.h", "some/library.a"], "package2": ["other/header.h"], } -def test_parse_kw_string_keys_without_values_default() -> None: - assert parse_kw_string("before-build; before-test: prepend", default_kw_value="append") == { +def test_parse_arbitrary_key_value_string_keys_without_values_default() -> None: + assert parse_arbitrary_key_value_string( + "before-build; before-test: prepend", default_value="append" + ) == { "before-build": ["append"], "before-test": ["prepend"], } -def test_parse_kw_string_keys_without_values_no_default() -> None: +def test_parse_arbitrary_key_value_string_keys_without_values_no_default() -> None: with pytest.raises(ValueError, match="No value specified"): - parse_kw_string("before-build") + parse_arbitrary_key_value_string("before-build") -def test_parse_kw_string_empty() -> None: - assert parse_kw_string("") == {} +def test_parse_arbitrary_key_value_string_empty() -> None: + assert parse_arbitrary_key_value_string("") == {} -def test_parse_kw_string_duplicate_keys() -> None: - assert parse_kw_string("key: val1; key: val2") == { +def test_parse_arbitrary_key_value_string_duplicate_keys() -> None: + assert parse_arbitrary_key_value_string("key: val1; key: val2") == { "key": ["val1", "val2"], } -def test_parse_kw_string_key_only_with_colon() -> None: - assert parse_kw_string("key:") == {"key": []} +def test_parse_arbitrary_key_value_string_key_only_with_colon() -> None: + assert parse_arbitrary_key_value_string("key:") == {"key": []} -def test_parse_kw_string_quoted_values() -> None: - assert parse_kw_string('key: "hello world"') == {"key": ["hello world"]} +def test_parse_arbitrary_key_value_string_quoted_values() -> None: + assert parse_arbitrary_key_value_string('key: "hello world"') == {"key": ["hello world"]} -def test_parse_kw_string_multiple_bare_keys_with_default() -> None: +def test_parse_arbitrary_key_value_string_multiple_bare_keys_with_default() -> None: """works, but should remain undocumented""" - assert parse_kw_string("a b c", default_kw_value="yes") == { + assert parse_arbitrary_key_value_string("a b c", default_value="yes") == { "a": ["yes"], "b": ["yes"], "c": ["yes"],