def test_args_evaluated(): T = TypeVar('T') assert typing_inspect.get_args(Union[int, Tuple[T, int]][str], evaluate=True) == (int, Tuple[str, int]) assert typing_inspect.get_args(Dict[int, Tuple[T, T]][Optional[int]], evaluate=True) == (int, Tuple[Optional[int], Optional[int]]) assert typing_inspect.get_args(Callable[[], T][int], evaluate=True) == ( [], int, ) assert typing_inspect.get_args(Union[int, Callable[[Tuple[T, ...]], str]], evaluate=True) == (int, Callable[[Tuple[T, ...]], str]) # ClassVar special-casing assert typing_inspect.get_args(ClassVar, evaluate=True) == () assert typing_inspect.get_args(ClassVar[int], evaluate=True) == (int, ) # Literal special-casing assert typing_inspect.get_args(Literal, evaluate=True) == () assert typing_inspect.get_args(Literal["value"], evaluate=True) == ("value", ) assert typing_inspect.get_args(Literal[1, 2, 3], evaluate=True) == (1, 2, 3)
def _from_list(obj: list, type_annotation: Annotation, xml_annotation: XMLAnnotation, element: Optional[_Element], config: SerializerConfig) -> _Element: item_annotation, *_rest = typing_inspect.get_args(type_annotation) if typing_inspect.is_annotated_type(item_annotation): item_type_annotation, item_xml_annotation = get_xml_annotation( item_annotation, DEFAULT_VALUE_ANNOTATION) else: item_type_annotation = item_annotation item_xml_annotation = xml_annotation if element is None: element = Element(xml_annotation.tag) if xml_annotation.tag == item_xml_annotation.tag: # siblings parent = element else: parent = _make_element(element, xml_annotation.tag) for item in obj: _from_obj(item, item_type_annotation, item_xml_annotation, parent, config) return parent
def _from_union(obj: Any, type_annotation: Annotation, json_annotation: JSONAnnotation, config: SerializerConfig) -> Any: for element_type in typing_inspect.get_args(type_annotation): try: return _from_any(obj, element_type, json_annotation, config) except: # pylint: disable=bare-except pass
def _from_union(obj: Any, type_annotation: Annotation, xml_annotation: XMLAnnotation, element: Optional[_Element], config: SerializerConfig) -> _Element: for union_type_annotation in typing_inspect.get_args(type_annotation): try: return _from_obj(obj, union_type_annotation, xml_annotation, element, config) except: # pylint: disable=bare-except pass raise ValueError('unable to find type that satisfies union')
def _from_list(lst: list, type_annotation: Annotation, config: SerializerConfig) -> Any: item_annotation, *_rest = typing_inspect.get_args(type_annotation) if typing_inspect.is_annotated_type(item_annotation): item_type_annotation, item_json_annotation = get_json_annotation( item_annotation) else: item_type_annotation = item_annotation item_json_annotation = JSONValue() return [ _from_any(item, item_type_annotation, item_json_annotation, config) for item in lst ]
def _from_optional(obj: Any, type_annotation: Annotation, json_annotation: JSONAnnotation, config: SerializerConfig) -> Any: if obj is None: return None # An optional is a union where the last element is the None type. union_types = typing_inspect.get_args(type_annotation)[:-1] if len(union_types) == 1: # This was Optional[T] return _from_any(obj, union_types[0], json_annotation, config) else: return _from_union(obj, Union[tuple(union_types)], json_annotation, config)
def _from_optional(obj: Any, type_annotation: Annotation, xml_annotation: XMLAnnotation, element: Optional[_Element], config: SerializerConfig) -> _Element: if obj is None: return _make_element(element, xml_annotation.tag) # An optional is a union where the last element is the None type. union_types = typing_inspect.get_args(type_annotation)[:-1] if len(union_types) == 1: # This was Optional[T] return _from_obj(obj, union_types[0], xml_annotation, element, config) else: return _from_union( obj, Union[tuple(union_types)], # type: ignore xml_annotation, element, config)
def _is_typed(annotation: Annotation) -> bool: return (typing_inspect.is_typed_dict_type(annotation) or (typing_inspect.is_list_type(annotation) and _is_typed(typing_inspect.get_args(annotation)[0])) or (typing_inspect.is_annotated_type(annotation) and _is_typed(typing_inspect.get_origin(annotation))))