From: Aleš Mrázek Date: Wed, 21 Jan 2026 20:28:44 +0000 (+0100) Subject: python: utils/modeling: fixed Literal bug for python 3.8 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3d5f1e86e18921b8ec385096806249ef8c9d6bb3;p=thirdparty%2Fknot-resolver.git python: utils/modeling: fixed Literal bug for python 3.8 This fixes bug created in MR !1768 logging improvements. --- diff --git a/python/knot_resolver/utils/modeling/base_schema.py b/python/knot_resolver/utils/modeling/base_schema.py index 93e59b9bd..6e83719d2 100644 --- a/python/knot_resolver/utils/modeling/base_schema.py +++ b/python/knot_resolver/utils/modeling/base_schema.py @@ -1,5 +1,6 @@ import enum import inspect +import sys from abc import ABC, abstractmethod # pylint: disable=[no-name-in-module] from typing import Any, Callable, Dict, Generic, List, Optional, Set, Tuple, Type, TypeVar, Union, cast @@ -354,7 +355,18 @@ class ObjectMapper: raise DataValidationError(f"expected bool, found {type(obj)}", object_path) def _create_literal(self, tp: Type[Any], obj: Any, object_path: str) -> Any: - expected = get_generic_type_arguments(tp) + args = get_generic_type_arguments(tp) + + expected = [] + if sys.version_info < (3, 9): + for arg in args: + if is_literal(arg): + expected += get_generic_type_arguments(arg) + else: + expected.append(arg) + else: + expected = args + if obj in expected: return obj raise DataValidationError(f"'{obj}' does not match any of the expected values {expected}", object_path) diff --git a/tests/manager/utils/modeling/test_base_schema.py b/tests/manager/utils/modeling/test_base_schema.py index 326996174..cb45f2211 100644 --- a/tests/manager/utils/modeling/test_base_schema.py +++ b/tests/manager/utils/modeling/test_base_schema.py @@ -19,6 +19,21 @@ class _TestStr(ConfigSchema): v: str +class _TestLiteral(ConfigSchema): + v: Literal[Literal["lit1"], Literal["lit2"]] + + +@pytest.mark.parametrize("val", ["lit1", "lit2"]) +def test_parsing_literal_valid(val: str): + assert _TestLiteral(parse_yaml(f"v: {val}")).v == val + + +@pytest.mark.parametrize("val", ["invalid", "false", 1, "null"]) +def test_parsing_literal_invalid(val: str): + with raises(DataValidationError): + _TestLiteral(parse_yaml(f"v: {val}")) + + @pytest.mark.parametrize("val,exp", [("false", False), ("true", True), ("False", False), ("True", True)]) def test_parsing_bool_valid(val: str, exp: bool): assert _TestBool(parse_yaml(f"v: {val}")).v == exp