def assert_expand(self, orig, map_items, result): lower_bounds = {} for id, t in map_items: lower_bounds[id] = t exp = expand_type(orig, lower_bounds) # Remove erased tags (asterisks). assert_equal(str(exp).replace('*', ''), str(result))
def apply_generic_arguments(self, callable, types, context): """Apply generic type arguments to a callable type. For example, applying [int] to 'def <T> (T) -> T' results in 'def [int] (int) -> int'. Here '[int]' is an implicit bound type variable. Note that each type can be None; in this case, it will not be applied. """ tvars = callable.variables.items if len(tvars) != len(types): self.msg.incompatible_type_application(len(tvars), len(types), context) return Any() # Create a map from type variable id to target type. id_to_type = {} for i, tv in enumerate(tvars): if types[i]: id_to_type[tv.id] = types[i] # Apply arguments to argument types. arg_types = [expand_type(at, id_to_type) for at in callable.arg_types] bound_vars = [(tv.id, id_to_type[tv.id]) for tv in tvars if tv.id in id_to_type] # The callable may retain some type vars if only some were applied. remaining_tvars = [tv for tv in tvars if tv.id not in id_to_type] return Callable(arg_types, callable.arg_kinds, callable.arg_names, expand_type(callable.ret_type, id_to_type), callable.is_type_obj(), callable.name, TypeVars(remaining_tvars), callable.bound_vars + bound_vars, callable.line, callable.repr)
def map_instance_to_direct_supertype( instance, supertype): typ = instance.typ for b in typ.bases: # The cast below cannot fail since we require that semantic analysis # was successful, so bases cannot contain unbound types. if b and (b).typ == supertype: map = type_var_map(typ, instance.args) return expand_type(b, map) # Relationship with the supertype not specified explicitly. Use dynamic # type arguments implicitly. return Instance(typ.base, [Any()] * len(typ.base.type_vars))
def map_instance_to_direct_supertypes( instance, supertype): # FIX: There should only be one supertypes, always. typ = instance.typ result = [] for b in typ.bases: # The cast below cannot fail since we require that semantic analysis # was successful, so bases cannot contain unbound types. if b and (b).typ == supertype: map = type_var_map(typ, instance.args) result.append(expand_type(b, map)) if result: return result else: # Relationship with the supertype not specified explicitly. Use dynamic # type arguments implicitly. return [Instance(supertype, [Any()] * len(supertype.type_vars))]
tvars.extend(callable.variables.items) if len(tvars) != len(types): self.msg.incompatible_type_application(len(tvars), len(types), context) return Any() # Create a map from type variable name to target type. dict<int, Typ> map = {} for i in range(len(tvars)): if types[i]: map[tvars[i].id] = types[i] Typ[] arg_types = [] for at in callable.arg_types: arg_types.append(expand_type(at, map)) list<tuple<int, Typ>> bound_vars = [] for tv in tvars: if tv.id in map: bound_vars.append((tv.id, map[tv.id])) return Callable(arg_types, callable.arg_kinds, callable.arg_names, expand_type(callable.ret_type, map), callable.is_type_obj(), callable.name, TypeVars([]), callable.bound_vars + bound_vars, callable.line, callable.repr)
instance.type.base) if instance.type == supertype: break return instance Instance map_instance_to_direct_supertype(Instance instance, TypeInfo supertype): typ = instance.type for b in typ.bases: # The cast below cannot fail since we require that semantic analysis # was successful, so bases cannot contain unbound types. if b and ((Instance)b).type == supertype: map = type_var_map(typ, instance.args) return (Instance)expand_type(b, map) # Relationship with the supertype not specified explicitly. Use dynamic # type arguments implicitly. return Instance(typ.base, <Type> [Any()] * len(typ.base.type_vars)) dict<int, Type> type_var_map(TypeInfo typ, Type[] args): if not args: return None else: tvars = <int, Type> {} for i in range(len(args)): tvars[i + 1] = args[i] return tvars