def _get_type_dict(inst: typing.Dict[KT, VT], use_union: bool) -> typing.Type[typing.Dict[KT, VT]]: from typish.functions._get_args import get_args t_list_k = _get_type_iterable(list(inst.keys()), use_union) t_list_v = _get_type_iterable(list(inst.values()), use_union) t_k_tuple = get_args(t_list_k) t_v_tuple = get_args(t_list_v) return typing.Dict[t_k_tuple[0], t_v_tuple[0]]
def _subclass_of_generic(cls: type, info_generic_type: type, info_args: typing.Tuple[type, ...]) -> bool: # Check if cls is a subtype of info_generic_type, knowing that the latter # is a generic type. from typish.functions._get_origin import get_origin from typish.functions._get_args import get_args result = False cls_origin = get_origin(cls) cls_args = get_args(cls) if info_generic_type is tuple: # Special case. result = (subclass_of(cls_origin, tuple) and _subclass_of_tuple(cls_args, info_args)) elif info_generic_type is typing.Union: # Another special case. result = any(subclass_of(cls, cls_) for cls_ in info_args) elif cls_origin is tuple and info_generic_type is typing.Iterable: # Another special case. args = _tuple_args(cls_args) # Match the number of arguments of info to that of cls. matched_info_args = info_args * len(args) result = _subclass_of_tuple(args, matched_info_args) elif (subclass_of(cls_origin, info_generic_type) and cls_args and len(cls_args) == len(info_args)): result = all(subclass_of(*tup) for tup in zip(cls_args, info_args)) # Note that issubtype(list, List[...]) is always False. # Note that the number of arguments must be equal. return result
def from_literal(literal: typing.Any) -> typing.Type['LiteralAlias']: """ Create a LiteralAlias from the given typing.Literal. :param literal: the typing.Literal type. :return: a LiteralAlias type. """ from typish.functions._get_args import get_args args = get_args(literal) return LiteralAlias[args] if args else LiteralAlias
def _subclass_of(cls: type, clsinfo: type) -> bool: from typish.functions._get_origin import get_origin from typish.functions._get_args import get_args # Check whether cls is a subtype of clsinfo. clsinfo_origin = get_origin(clsinfo) clsinfo_args = get_args(clsinfo) cls_origin = get_origin(cls) if cls is Unknown or clsinfo in (typing.Any, object): result = True elif cls_origin is typing.Union: # cls is a Union; all options of that Union must subclass clsinfo. cls_args = get_args(cls) result = all([subclass_of(elem, clsinfo) for elem in cls_args]) elif clsinfo_args: result = _subclass_of_generic(cls, clsinfo_origin, clsinfo_args) else: try: result = issubclass(cls_origin, clsinfo_origin) except TypeError: result = False return result
def _forward_subclass_check(cls: type, clsinfo: type) -> bool: # Forward the subclass check for cls and clsinfo to delegates that know how # to check that particular cls/clsinfo type. from typish.functions._get_origin import get_origin from typish.functions._get_args import get_args clsinfo_origin = get_origin(clsinfo) clsinfo_args = get_args(clsinfo) cls_origin = get_origin(cls) if cls_origin is typing.Union: # cls is a Union; all options of that Union must subclass clsinfo. cls_args = get_args(cls) result = all([subclass_of(elem, clsinfo) for elem in cls_args]) elif clsinfo_args: result = _subclass_of_generic(cls, clsinfo_origin, clsinfo_args) else: try: result = issubclass(cls_origin, clsinfo_origin) except TypeError: result = False return result