diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 36ebe68e..2b076e4a 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -19,17 +19,19 @@ Added ^^^^^ - Support for Python 3.13 (`#554 `__). -- Support for `NotRequired` and `Required` annotations for `TypedDict` keys - (`#571 `__). +- Support for ``NotRequired`` and ``Required`` annotations for ``TypedDict`` + keys (`#571 `__). Fixed ^^^^^ - Callable type with subclass return not showing the ``--*.help`` option (`#567 `__). -- Forward referenced types not compatible with `Type` typehint (`#576 +- Forward referenced types not compatible with ``Type`` typehint (`#576 `__). - Subclass nested in ``Iterable`` makes help fail (`#578 `__). +- ``Literal`` mixing enum values and strings failing to parse (`#580 + `__). Changed ^^^^^^^ diff --git a/jsonargparse/_typehints.py b/jsonargparse/_typehints.py index 50a119b8..3a2f8548 100644 --- a/jsonargparse/_typehints.py +++ b/jsonargparse/_typehints.py @@ -760,7 +760,7 @@ def adapt_typehints( # Literal elif typehint_origin in literal_types: if val not in subtypehints and isinstance(val, str): - subtypes = Union[tuple({type(v) for v in subtypehints})] + subtypes = Union[tuple({type(v) for v in subtypehints if type(v) is not str})] val = adapt_typehints(val, subtypes, **adapt_kwargs) if val not in subtypehints: raise_unexpected_value(f"Expected a {typehint}", val) diff --git a/jsonargparse_tests/test_typehints.py b/jsonargparse_tests/test_typehints.py index f8f2cde9..417f2db3 100644 --- a/jsonargparse_tests/test_typehints.py +++ b/jsonargparse_tests/test_typehints.py @@ -248,6 +248,16 @@ def test_enum_str_optional(parser): assert None is parser.parse_args(["--enum=null"]).enum +@pytest.mark.skipif(not Literal, reason="Literal introduced in python 3.8 or backported in typing_extensions") +def test_literal_enum_values(parser): + parser.add_argument("--enum", type=Literal[EnumABC.A, EnumABC.C, "X"]) + assert EnumABC.A == parser.parse_args(["--enum=A"]).enum + assert EnumABC.C == parser.parse_args(["--enum=C"]).enum + assert "X" == parser.parse_args(["--enum=X"]).enum + with pytest.raises(ArgumentError, match="Expected a typing.*.Literal"): + parser.parse_args(["--enum=B"]) + + # set tests