def is_overlapping_erased_types(left: Type, right: Type, *, ignore_promotions: bool = False) -> bool: """The same as 'is_overlapping_erased_types', except the types are erased first.""" return is_overlapping_types(erase_type(left), erase_type(right), ignore_promotions=ignore_promotions, prohibit_none_typevar_overlap=True)
def check_instance_definition( passed_types: TupleType, instance_signature: CallableType, fullname: str, ctx: MethodContext, ) -> _RuntimeValidationContext: """ Checks runtime type. We call "runtime types" things that we use at runtime to dispatch our calls. For example: 1. We check that type passed in ``some.instance(...)`` matches one defined in a type annotation 2. We check that types don't have any concrete types 3. We check that types don't have any unbound type variables 4. We check that ``is_protocol`` is passed correctly """ runtime_type = inference.infer_runtime_type_from_context( fallback=passed_types.items[0], fullname=fullname, ctx=ctx, ) if len(passed_types.items) == 2: is_protocol, protocol_arg_check = _check_protocol_arg(passed_types, ctx) else: is_protocol = False protocol_arg_check = True instance_type = instance_signature.arg_types[0] instance_check = is_same_type( erase_type(instance_type), erase_type(runtime_type), ) if not instance_check: ctx.api.fail( _INSTANCE_RUNTIME_MISMATCH_MSG.format(instance_type, runtime_type), ctx.context, ) return _RuntimeValidationContext(runtime_type, is_protocol, all([ _check_runtime_protocol(runtime_type, ctx, is_protocol=is_protocol), _check_concrete_generics(runtime_type, instance_type, ctx), _check_tuple_size(instance_type, ctx), protocol_arg_check, instance_check, ]))
def restrict_subtype_away(t: Type, s: Type) -> Type: """Return t minus s. If we can't determine a precise result, return a supertype of the ideal result (just t is a valid result). This is used for type inference of runtime type checks such as isinstance. Currently this just removes elements of a union type. """ if isinstance(t, UnionType): # Since runtime type checks will ignore type arguments, erase the types. erased_s = erase_type(s) new_items = [item for item in t.relevant_items() if (not is_proper_subtype(erase_type(item), erased_s) or isinstance(item, AnyType))] return UnionType.make_union(new_items) else: return t
def format(self, typ: Type, verbosity: int = 0) -> str: """Convert a type to a relatively short string that is suitable for error messages. Mostly behave like format_simple below, but never return an empty string. """ s = self.format_simple(typ, verbosity) if s != '': # If format_simple returns a non-trivial result, use that. return s elif isinstance(typ, FunctionLike): func = typ if func.is_type_obj(): # The type of a type object type can be derived from the # return type (this always works). return self.format( TypeType.make_normalized( erase_type(func.items()[0].ret_type)), verbosity) elif isinstance(func, CallableType): return_type = strip_quotes(self.format(func.ret_type)) if func.is_ellipsis_args: return 'Callable[..., {}]'.format(return_type) arg_strings = [] for arg_name, arg_type, arg_kind in zip( func.arg_names, func.arg_types, func.arg_kinds): if (arg_kind == ARG_POS and arg_name is None or verbosity == 0 and arg_kind in (ARG_POS, ARG_OPT)): arg_strings.append( strip_quotes( self.format(arg_type, verbosity=max(verbosity - 1, 0)))) else: constructor = ARG_CONSTRUCTOR_NAMES[arg_kind] if arg_kind in (ARG_STAR, ARG_STAR2) or arg_name is None: arg_strings.append("{}({})".format( constructor, strip_quotes(self.format(arg_type)))) else: arg_strings.append("{}({}, {})".format( constructor, strip_quotes(self.format(arg_type)), repr(arg_name))) return 'Callable[[{}], {}]'.format(", ".join(arg_strings), return_type) else: # Use a simple representation for function types; proper # function types may result in long and difficult-to-read # error messages. return 'overloaded function' else: # Default case; we simply have to return something meaningful here. return 'object'
def restrict_subtype_away(t: Type, s: Type) -> Type: """Return t minus s. If we can't determine a precise result, return a supertype of the ideal result (just t is a valid result). This is used for type inference of runtime type checks such as isinstance. Currently this just removes elements of a union type. """ if isinstance(t, UnionType): # Since runtime type checks will ignore type arguments, erase the types. erased_s = erase_type(s) # TODO: Implement more robust support for runtime isinstance() checks, # see issue #3827 new_items = [item for item in t.relevant_items() if (not (is_proper_subtype(erase_type(item), erased_s) or is_proper_subtype(item, erased_s)) or isinstance(item, AnyType))] return UnionType.make_union(new_items) else: return t
def assert_erase(self, orig, result): assert_equal(str(erase_type(orig)), str(result))
def assert_erase(self, orig: Type, result: Type) -> None: assert_equal(str(erase_type(orig)), str(result))
def assert_erase(self, orig, result): assert_equal(str(erase_type(orig, self.fx.basic)), str(result))