def test_merge_tag_handler() -> None: """Merge tag handler should correctly merge dictionnaries & lists.""" # Merging list should work _check_merge_tag( ListField(StringField()), "!merge [[value_1, value_2], [value_3]]", ["value_1", "value_2", "value_3"], ) # Merging dicts should work _check_merge_tag( DictField(StringField()), "!merge [{a: a_value, b: b_value}, {b: overwrite_b}]", { "a": "a_value", "b": "overwrite_b" }, ) # An undefined value in the sequence should be ignored _check_merge_tag( ListField(StringField()), "!merge [[value_1, value_2], !fail [value_3]]", ["value_1", "value_2"], ) # An empty sequence should return UNDEFINED _check_merge_tag(ListField(StringField()), "!merge []", UNDEFINED)
def test_if_tag_handler() -> None: """If tag should load value only if tag is defined.""" result = check_load( "!if(FLAG) test_value", field=StringField(), tag_handlers=[IfHandler()], config=[IfHandler.Config({"FLAG"})], ) assert result == "test_value" result = check_load( "!if(UNDEFINED) test_value", field=StringField(), tag_handlers=[IfHandler()], config=[IfHandler.Config({"FLAG"})], ) assert result == UNDEFINED result = check_load( "!if(FLAG) {key: value}", field=DictField(StringField()), tag_handlers=[IfHandler()], config=[IfHandler.Config({"FLAG"})], ) assert result == {"key": "value"} result = check_load( "!if(FLAG) [item]", field=ListField(StringField()), tag_handlers=[IfHandler()], config=[IfHandler.Config({"FLAG"})], ) assert result == ["item"]
class _Test: fields = {"list": ListField(StringField())} def __init__(self) -> None: """Initialize _Test.""" self.field: Optional[List[str]] = None
def test_merge_tag_handler_error_handling() -> None: """Merge tag should correctly handle errors.""" _check_merge_tag( ListField(StringField()), "!merge scalar_value", expected_error=ErrorCode.UNEXPECTED_NODE_TYPE, ) _check_merge_tag( ListField(StringField()), "!merge {}", expected_error=ErrorCode.UNEXPECTED_NODE_TYPE, ) _check_merge_tag(StringField(), "!merge [scalar_value]", expected_error=ErrorCode.VALUE_ERROR)
class _Owner: fields = { "object_field": ObjectField(object_class=_Owned), "object_list": ListField(ObjectField(object_class=_Owned)), } def __init__(self) -> None: self.object_field = None self.object_list = None
def _build_field(field_type: Type[Any]): if field_type in _LITERAL_FIELD_MAPPINGS: return _LITERAL_FIELD_MAPPINGS[field_type]() origin_type = get_origin(field_type) type_args = get_args(field_type) if origin_type == list: assert len(type_args) == 1 nested_field = _build_field(type_args[0]) return ListField(nested_field) if origin_type == dict: assert len(type_args) == 2 assert type_args[0] == str nested_field = _build_field(type_args[1]) return DictField(nested_field) return ObjectField(field_type)
def check_path_tag_error( handler_type: Type[PathHandler], yaml: str, expected_error: ErrorCode, location: Optional[str] = None, allow_relative: bool = True, roots: Optional[List[Path]] = None, expected_value: Any = UNDEFINED, ) -> None: """Path tag hanhler inherited tags error test helper.""" result = check_load( yaml, field=ListField(StringField()), expected_error=expected_error, location=location, tag_handlers=[handler_type(allow_relative=allow_relative)], config=[PathHandler.Config(roots)], ) assert result == expected_value
def check_path_tag( handler_type: Type[PathHandler], yaml: str, expected_value: Any, allow_relative: bool = True, location: Optional[Path] = None, roots: Optional[List[Path]] = None, ) -> None: """Path tag hanhler inherited tags test helper.""" result = check_load( yaml, field=ListField(StringField()), tag_handlers=[handler_type(allow_relative=allow_relative)], config=[PathHandler.Config(roots=[] if roots is None else roots, )], location=str(location), ) # for glob tag handler. if isinstance(expected_value, list): assert sorted(result) == sorted(expected_value) else: assert result == expected_value
from marshpy.fields.int_field import IntField from marshpy.fields.list_field import ListField from marshpy.fields.object_field import ObjectField from marshpy.fields.string_field import StringField from marshpy.tag_handlers.env_handler import EnvHandler from marshpy.tag_handlers.glob_handler import GlobHandler from marshpy.tag_handlers.if_handler import IfHandler from marshpy.tag_handlers.import_handler import ImportHandler from marshpy.tag_handlers.tag_handler import TagHandler _ROOT_FIELDS_MAPPING = { bool: BoolField(), dict: DictField(StringField()), float: FloatField(), int: IntField(), list: ListField(StringField()), str: StringField(), } ObjectType = TypeVar("ObjectType") def load( # pylint: disable=too-many-locals source: Union[str, IO[str]], object_class: Optional[Type[ObjectType]] = None, tag_handlers: Optional[Iterable[TagHandler]] = None, error_handler: Optional[ErrorHandler] = None, root_field: Optional[BaseField] = None, config: Optional[List[Any]] = None, ) -> LoadResult[ObjectType]: """Deserialize a YAML file, stream or string into an object.