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))
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))
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))
def test_cannot_obtain_args_of_non_generics() -> None: expectation: Tuple[Type, ...] = tuple() assert args_of(NameJson) == expectation
def test_can_obtain_args_of_generics() -> None: expectation = (int, str) assert args_of(GenericJson[int, str]) == expectation