예제 #1
0
def decode_as_tuple(
    type_: Type[Decoded], json: Any, path: Path
) -> Union[Decoded, DecodingError]:
    from typedjson.annotation import args_of
    from typedjson.annotation import origin_of

    def _required_length(args: Tuple[Type, ...]) -> int:
        return len(args) - 2 if args[-1] is ... else len(args)

    def _iter_args(args: Tuple[Type, ...]) -> Iterator[Type]:
        last: Optional[Type] = None
        for type_ in args:
            if type_ is ...:
                if last is None:
                    raise
                else:
                    while True:
                        yield last
            else:
                yield type_
            last = type_

    if origin_of(type_) is tuple:
        if json is None:
            return DecodingError(TypeMismatch(path))

        list_decoded: List[Any] = []
        length = len(json)
        if _required_length(args_of(type_)) > length:
            return DecodingError(TypeMismatch(path))

        for (index, (type_, element)) in enumerate(
            zip(_iter_args(args_of(type_)), json)
        ):
            decoded = decode(type_, element, path + (str(index),))
            if isinstance(decoded, DecodingError):
                return decoded

            list_decoded.append(decoded)

        return tuple(list_decoded)  # type: ignore
    else:
        return DecodingError(UnsupportedDecoding(path))
예제 #2
0
def decode_as_union(type_: Type[Decoded], json: Any,
                    path: Path) -> Union[Decoded, DecodingError]:
    from typedjson.annotation import args_of
    from typedjson.annotation import origin_of

    if origin_of(type_) is Union:
        args = args_of(type_)
        for type_ in args:
            if type_.__class__ is TypeVar:
                return DecodingError(UnsupportedDecoding(path))

        for type_ in args:
            decoded = decode(type_, json, path)
            if not isinstance(decoded, DecodingError):
                break

        return decoded
    else:
        return DecodingError(UnsupportedDecoding(path))
예제 #3
0
def decode_as_list(type_: Type[Decoded], json: Any,
                   path: Path) -> Union[Decoded, DecodingError]:
    from typedjson.annotation import args_of
    from typedjson.annotation import origin_of

    if origin_of(type_) is list:
        Element = args_of(type_)[0]
        list_decoded: List[Any] = []

        for index, element in enumerate(json):
            decoded = decode(Element, element, path + (str(index), ))
            if isinstance(decoded, DecodingError):
                return decoded

            list_decoded.append(decoded)

        return list(list_decoded)  # type: ignore
    else:
        return DecodingError(UnsupportedDecoding(path))
예제 #4
0
def test_cannot_obtain_args_of_non_generics() -> None:
    expectation: Tuple[Type, ...] = tuple()
    assert args_of(NameJson) == expectation
예제 #5
0
def test_can_obtain_args_of_generics() -> None:
    expectation = (int, str)
    assert args_of(GenericJson[int, str]) == expectation