From 1af88b5f03e95c73673d1509a6a47c41f683429e Mon Sep 17 00:00:00 2001 From: Marcelo Da Cruz Pinto Date: Tue, 31 Oct 2023 00:34:03 +0000 Subject: [PATCH] Adding literal support --- dataconf/utils.py | 9 ++++++++- tests/test_parse.py | 37 ++++++++++++++++++++++++++++++++++++- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/dataconf/utils.py b/dataconf/utils.py index a971510..943e4e8 100644 --- a/dataconf/utils.py +++ b/dataconf/utils.py @@ -7,7 +7,7 @@ from enum import IntEnum from inspect import isclass -from typing import Any +from typing import Any, Literal from typing import Dict from typing import get_args from typing import get_origin @@ -200,6 +200,13 @@ def __parse(value: any, clazz: Type, path: str, strict: bool, ignore_unexpected: raise TypeConfigException(f"expected str or int at {path}, got {type(value)}") + if get_origin(clazz) is (Literal): + if value in args: + return value + raise TypeConfigException( + f"expected one of {', '.join(map(str, args))} at {path}, got {value}" + ) + if clazz is datetime: dt = __parse_type(value, clazz, path, isinstance(value, str)) try: diff --git a/tests/test_parse.py b/tests/test_parse.py index 24b81f7..9ee9c96 100644 --- a/tests/test_parse.py +++ b/tests/test_parse.py @@ -5,7 +5,7 @@ from enum import Enum from enum import IntEnum import os -from typing import Any +from typing import Any, Literal from typing import Dict from typing import List from typing import Optional @@ -712,3 +712,38 @@ class TopLevel: top_b="some other value", top_c=Nested(nested_a=False, nested_b="some default value"), ) + + def test_literals(self): + @dataclass + class Something: + literal: Literal["a", "b", 3] = field(default="a") + + config_string = """ + literal: "a" + """ + + assert loads(config_string, Something, loader=dataconf.YAML) == Something( + literal="a" + ) + + config_string = """ + literal: "b" + """ + + assert loads(config_string, Something, loader=dataconf.YAML) == Something( + literal="b" + ) + + config_string = """ + literal: 3 + """ + + assert loads(config_string, Something, loader=dataconf.YAML) == Something( + literal=3 + ) + + with pytest.raises(TypeConfigException): + config_string = """ + literal: "d" + """ + loads(config_string, Something, loader=dataconf.YAML)