diff --git a/CHANGELOG.rst b/CHANGELOG.rst index b58a8eee..ff55af54 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -12,6 +12,14 @@ The semantic versioning only considers the public API as described in paths are considered internals and can change in minor and patch releases. +v4.26.1 (2023-10-??) +-------------------- + +Fixed +^^^^^ +- Failures when choices is a ``dict_keys`` object and value non-hashable. + + v4.26.0 (2023-10-19) -------------------- diff --git a/jsonargparse/_core.py b/jsonargparse/_core.py index d8056df2..da99a6b9 100644 --- a/jsonargparse/_core.py +++ b/jsonargparse/_core.py @@ -131,6 +131,8 @@ def add_argument(self, *args, enable_path: bool = False, **kwargs): container=super(), logger=self._logger, ) + if "choices" in kwargs and not isinstance(kwargs["choices"], (list, tuple)): + kwargs["choices"] = tuple(kwargs["choices"]) action = super().add_argument(*args, **kwargs) action.logger = self._logger # type: ignore ActionConfigFile._add_print_config_argument(self, action) diff --git a/jsonargparse_tests/test_core.py b/jsonargparse_tests/test_core.py index 07cd4ac0..b0d01402 100644 --- a/jsonargparse_tests/test_core.py +++ b/jsonargparse_tests/test_core.py @@ -156,6 +156,15 @@ def test_parse_args_choices_config(parser): pytest.raises(ArgumentError, lambda: parser.parse_args(["--cfg=ch2: v0"])) +def test_parse_args_non_hashable_choice(parser): + choices = {"A": 1, "B": 2} + parser.add_argument("--cfg", action=ActionConfigFile) + parser.add_argument("--ch1", choices=choices.keys()) + with pytest.raises(ArgumentError) as ctx: + parser.parse_args(["--cfg=ch1: [1,2]"]) + ctx.match("not among choices") + + def test_parse_object_simple(parser): parser.add_argument("--op", type=int) assert parser.parse_object({"op": 1}) == Namespace(op=1)