コード例 #1
0
    def visit_callable_type(self, t: CallableType) -> Type:
        param_spec = t.param_spec()
        if param_spec is not None:
            repl = get_proper_type(self.variables.get(param_spec.id))
            # If a ParamSpec in a callable type is substituted with a
            # callable type, we can't use normal substitution logic,
            # since ParamSpec is actually split into two components
            # *P.args and **P.kwargs in the original type. Instead, we
            # must expand both of them with all the argument types,
            # kinds and names in the replacement. The return type in
            # the replacement is ignored.
            if isinstance(repl, CallableType) or isinstance(repl, Parameters):
                # Substitute *args: P.args, **kwargs: P.kwargs
                prefix = param_spec.prefix
                # we need to expand the types in the prefix, so might as well
                # not get them in the first place
                t = t.expand_param_spec(repl, no_prefix=True)
                return t.copy_modified(
                    arg_types=self.expand_types(prefix.arg_types) +
                    t.arg_types,
                    arg_kinds=prefix.arg_kinds + t.arg_kinds,
                    arg_names=prefix.arg_names + t.arg_names,
                    ret_type=t.ret_type.accept(self),
                    type_guard=(t.type_guard.accept(self)
                                if t.type_guard is not None else None))

        return t.copy_modified(arg_types=self.expand_types(t.arg_types),
                               ret_type=t.ret_type.accept(self),
                               type_guard=(t.type_guard.accept(self) if
                                           t.type_guard is not None else None))
コード例 #2
0
ファイル: typeops.py プロジェクト: sthagen/mypy
def class_callable(init_type: CallableType,
                   info: TypeInfo,
                   type_type: Instance,
                   special_sig: Optional[str],
                   is_new: bool,
                   orig_self_type: Optional[Type] = None) -> CallableType:
    """Create a type object type based on the signature of __init__."""
    variables: List[TypeVarLikeType] = []
    variables.extend(info.defn.type_vars)
    variables.extend(init_type.variables)

    from mypy.subtypes import is_subtype

    init_ret_type = get_proper_type(init_type.ret_type)
    orig_self_type = get_proper_type(orig_self_type)
    default_ret_type = fill_typevars(info)
    explicit_type = init_ret_type if is_new else orig_self_type
    if (isinstance(explicit_type, (Instance, TupleType))
            # Only use the declared return type from __new__ or declared self in __init__
            # if it is actually returning a subtype of what we would return otherwise.
            and is_subtype(
                explicit_type, default_ret_type, ignore_type_params=True)):
        ret_type: Type = explicit_type
    else:
        ret_type = default_ret_type

    callable_type = init_type.copy_modified(ret_type=ret_type,
                                            fallback=type_type,
                                            name=None,
                                            variables=variables,
                                            special_sig=special_sig)
    c = callable_type.with_name(info.name)
    return c
コード例 #3
0
ファイル: typeanal.py プロジェクト: matthiaskramm/mypy
 def visit_callable_type(self, t: CallableType) -> Type:
     return t.copy_modified(
         arg_types=self.anal_array(t.arg_types),
         ret_type=t.ret_type.accept(self),
         fallback=t.fallback or self.builtin_type("builtins.function"),
         variables=self.anal_var_defs(t.variables),
     )
コード例 #4
0
ファイル: typeanal.py プロジェクト: sevajide/mypy
 def visit_callable_type(self, t: CallableType) -> Type:
     return t.copy_modified(arg_types=self.anal_array(t.arg_types),
                            ret_type=t.ret_type.accept(self),
                            fallback=t.fallback
                            or self.builtin_type('builtins.function'),
                            variables=self.anal_var_defs(t.variables),
                            bound_vars=self.anal_bound_vars(t.bound_vars))
コード例 #5
0
ファイル: plugin.py プロジェクト: rmoorman/mypy
def typed_dict_get_signature_callback(
        object_type: Type, args: List[List[Expression]],
        signature: CallableType,
        named_generic_type: Callable[[str, List[Type]], Type]) -> CallableType:
    """Try to infer a better signature type for TypedDict.get.

    This is used to get better type context for the second argument that
    depends on a TypedDict value type.
    """
    if (isinstance(object_type, TypedDictType) and len(args) == 2
            and len(args[0]) == 1 and isinstance(args[0][0], StrExpr)
            and len(signature.arg_types) == 2
            and len(signature.variables) == 1):
        key = args[0][0].value
        value_type = object_type.items.get(key)
        if value_type:
            # Tweak the signature to include the value type as context. It's
            # only needed for type inference since there's a union with a type
            # variable that accepts everything.
            tv = TypeVarType(signature.variables[0])
            return signature.copy_modified(arg_types=[
                signature.arg_types[0],
                UnionType.make_simplified_union([value_type, tv])
            ])
    return signature
コード例 #6
0
def apply_generic_arguments(callable: CallableType, types: List[Type],
                            msg: MessageBuilder,
                            context: Context) -> CallableType:
    """Apply generic type arguments to a callable type.

    For example, applying [int] to 'def [T] (T) -> T' results in
    'def (int) -> int'.

    Note that each type can be None; in this case, it will not be applied.
    """
    tvars = callable.variables
    assert len(tvars) == len(types)
    # Check that inferred type variable values are compatible with allowed
    # values and bounds.  Also, promote subtype values to allowed values.
    types = types[:]
    for i, type in enumerate(types):
        values = callable.variables[i].values
        if values and type:
            if isinstance(type, AnyType):
                continue
            if isinstance(type, TypeVarType) and type.values:
                # Allow substituting T1 for T if every allowed value of T1
                # is also a legal value of T.
                if all(
                        any(is_same_type(v, v1) for v in values)
                        for v1 in type.values):
                    continue
            for value in values:
                if isinstance(type, PartialType) or mypy.subtypes.is_subtype(
                        type, value):
                    types[i] = value
                    break
            else:
                msg.incompatible_typevar_value(callable, type,
                                               callable.variables[i].name,
                                               context)
        upper_bound = callable.variables[i].upper_bound
        if (type and not isinstance(type, PartialType)
                and not mypy.subtypes.is_subtype(type, upper_bound)):
            msg.incompatible_typevar_value(callable, type,
                                           callable.variables[i].name, context)

    # Create a map from type variable id to target type.
    id_to_type = {}  # type: Dict[TypeVarId, 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]

    # 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.copy_modified(
        arg_types=arg_types,
        ret_type=expand_type(callable.ret_type, id_to_type),
        variables=remaining_tvars,
    )
コード例 #7
0
ファイル: suggestions.py プロジェクト: rakanalh/mypy
    def get_guesses(self, is_method: bool, base: CallableType, defaults: List[Optional[Type]],
                    callsites: List[Callsite]) -> List[CallableType]:
        """Compute a list of guesses for a function's type.

        This focuses just on the argument types, and doesn't change the provided return type.
        """
        options = self.get_args(is_method, base, defaults, callsites)
        return [base.copy_modified(arg_types=list(x)) for x in itertools.product(*options)]
コード例 #8
0
 def visit_callable_type(self, t: CallableType) -> Type:
     return t.copy_modified(arg_types=self.anal_array(t.arg_types,
                                                      nested=False),
                            ret_type=self.anal_type(t.ret_type,
                                                    nested=False),
                            fallback=t.fallback
                            or self.builtin_type('builtins.function'),
                            variables=self.anal_var_defs(t.variables))
コード例 #9
0
ファイル: suggestions.py プロジェクト: Michael0x2a/mypy
    def get_guesses(self, is_method: bool, base: CallableType, defaults: List[Optional[Type]],
                    callsites: List[Callsite]) -> List[CallableType]:
        """Compute a list of guesses for a function's type.

        This focuses just on the argument types, and doesn't change the provided return type.
        """
        options = self.get_args(is_method, base, defaults, callsites)
        return [base.copy_modified(arg_types=list(x)) for x in itertools.product(*options)]
コード例 #10
0
def refine_callable(t: CallableType, s: CallableType) -> CallableType:
    """Refine a callable based on another.

    See comments for refine_type.
    """
    if t.fallback != s.fallback:
        return t

    if t.is_ellipsis_args and not is_tricky_callable(s):
        return s.copy_modified(ret_type=refine_type(t.ret_type, s.ret_type))

    if is_tricky_callable(t) or t.arg_kinds != s.arg_kinds:
        return t

    return t.copy_modified(
        arg_types=[refine_type(ta, sa) for ta, sa in zip(t.arg_types, s.arg_types)],
        ret_type=refine_type(t.ret_type, s.ret_type),
    )
コード例 #11
0
ファイル: applytype.py プロジェクト: AXGKl/Transcrypt
def apply_generic_arguments(callable: CallableType, types: List[Type],
                            msg: MessageBuilder, context: Context) -> Type:
    """Apply generic type arguments to a callable type.

    For example, applying [int] to 'def [T] (T) -> T' results in
    'def (int) -> int'.

    Note that each type can be None; in this case, it will not be applied.
    """
    tvars = callable.variables
    if len(tvars) != len(types):
        msg.incompatible_type_application(len(tvars), len(types), context)
        return AnyType()

    # Check that inferred type variable values are compatible with allowed
    # values and bounds.  Also, promote subtype values to allowed values.
    types = types[:]
    for i, type in enumerate(types):
        values = callable.variables[i].values
        if values and type:
            if isinstance(type, AnyType):
                continue
            if isinstance(type, TypeVarType) and type.values:
                # Allow substituting T1 for T if every allowed value of T1
                # is also a legal value of T.
                if all(any(is_same_type(v, v1) for v in values)
                       for v1 in type.values):
                    continue
            for value in values:
                if mypy.subtypes.is_subtype(type, value):
                    types[i] = value
                    break
            else:
                msg.incompatible_typevar_value(callable, i + 1, type, context)

        upper_bound = callable.variables[i].upper_bound
        if type and not mypy.subtypes.satisfies_upper_bound(type, upper_bound):
            msg.incompatible_typevar_value(callable, i + 1, type, context)

    # Create a map from type variable id to target type.
    id_to_type = {}  # type: Dict[TypeVarId, 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]

    # 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.copy_modified(
        arg_types=arg_types,
        ret_type=expand_type(callable.ret_type, id_to_type),
        variables=remaining_tvars,
    )
コード例 #12
0
def apply_generic_arguments(
        callable: CallableType, orig_types: Sequence[Optional[Type]],
        report_incompatible_typevar_value: Callable[[CallableType, Type, str, Context], None],
        context: Context,
        skip_unsatisfied: bool = False) -> CallableType:
    """Apply generic type arguments to a callable type.

    For example, applying [int] to 'def [T] (T) -> T' results in
    'def (int) -> int'.

    Note that each type can be None; in this case, it will not be applied.

    If `skip_unsatisfied` is True, then just skip the types that don't satisfy type variable
    bound or constraints, instead of giving an error.
    """
    tvars = callable.variables
    assert len(tvars) == len(orig_types)
    # Check that inferred type variable values are compatible with allowed
    # values and bounds.  Also, promote subtype values to allowed values.
    types = get_proper_types(orig_types)

    # Create a map from type variable id to target type.
    id_to_type: Dict[TypeVarId, Type] = {}

    for tvar, type in zip(tvars, types):
        assert not isinstance(type, PartialType), "Internal error: must never apply partial type"
        if type is None:
            continue

        target_type = get_target_type(
            tvar, type, callable, report_incompatible_typevar_value, context, skip_unsatisfied
        )
        if target_type is not None:
            id_to_type[tvar.id] = target_type

    param_spec = callable.param_spec()
    if param_spec is not None:
        nt = id_to_type.get(param_spec.id)
        if nt is not None:
            nt = get_proper_type(nt)
            if isinstance(nt, CallableType):
                callable = callable.expand_param_spec(nt)

    # Apply arguments to argument types.
    arg_types = [expand_type(at, id_to_type) for at in callable.arg_types]

    # 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.copy_modified(
        arg_types=arg_types,
        ret_type=expand_type(callable.ret_type, id_to_type),
        variables=remaining_tvars,
    )
コード例 #13
0
ファイル: semanal_pass3.py プロジェクト: yuzhoujr/spazzatura
 def visit_callable_type(self, t: CallableType) -> Type:
     if self.check_recursion(t):
         return AnyType(TypeOfAny.from_error)
     arg_types = [tp.accept(self) for tp in t.arg_types]
     ret_type = t.ret_type.accept(self)
     variables = t.variables.copy()
     for v in variables:
         if v.upper_bound:
             v.upper_bound = v.upper_bound.accept(self)
         if v.values:
             v.values = [val.accept(self) for val in v.values]
     return t.copy_modified(arg_types=arg_types, ret_type=ret_type, variables=variables)
コード例 #14
0
ファイル: checkmember.py プロジェクト: zhoujiamurong/mypy
def class_callable(init_type: CallableType, info: TypeInfo, type_type: Instance,
                   special_sig: Optional[str]) -> CallableType:
    """Create a type object type based on the signature of __init__."""
    variables = []  # type: List[TypeVarDef]
    variables.extend(info.defn.type_vars)
    variables.extend(init_type.variables)

    callable_type = init_type.copy_modified(
        ret_type=fill_typevars(info), fallback=type_type, name=None, variables=variables,
        special_sig=special_sig)
    c = callable_type.with_name(info.name())
    return c
コード例 #15
0
ファイル: decorators.py プロジェクト: zeta1999/returns
def _change_decorator_function_type(
    decorator: CallableType,
    arg_type: CallableType,
) -> CallableType:
    """Replaces revealed argument types by mypy with types from decorated."""
    return decorator.copy_modified(
        arg_types=arg_type.arg_types,
        arg_kinds=arg_type.arg_kinds,
        arg_names=arg_type.arg_names,
        variables=arg_type.variables,
        is_ellipsis_args=arg_type.is_ellipsis_args,
    )
コード例 #16
0
ファイル: typeanal.py プロジェクト: Teraisa/flask-advanced
 def visit_callable_type(self, t: CallableType, nested: bool = True) -> Type:
     # Every Callable can bind its own type variables, if they're not in the outer scope
     with self.tvar_scope_frame():
         if self.aliasing:
             variables = t.variables
         else:
             variables = self.bind_function_type_variables(t, t)
         ret = t.copy_modified(arg_types=self.anal_array(t.arg_types, nested=nested),
                               ret_type=self.anal_type(t.ret_type, nested=nested),
                               fallback=t.fallback or self.named_type('builtins.function'),
                               variables=self.anal_var_defs(variables))
     return ret
コード例 #17
0
ファイル: semanal_pass3.py プロジェクト: sixolet/mypy
 def visit_callable_type(self, t: CallableType) -> Type:
     if self.check_recursion(t):
         return AnyType(TypeOfAny.from_error)
     arg_types = [tp.accept(self) for tp in t.arg_types]
     ret_type = t.ret_type.accept(self)
     variables = t.variables.copy()
     for v in variables:
         if v.upper_bound:
             v.upper_bound = v.upper_bound.accept(self)
         if v.values:
             v.values = [val.accept(self) for val in v.values]
     return t.copy_modified(arg_types=arg_types, ret_type=ret_type, variables=variables)
コード例 #18
0
ファイル: checkmember.py プロジェクト: Michael0x2a/mypy
def class_callable(init_type: CallableType, info: TypeInfo, type_type: Instance,
                   special_sig: Optional[str]) -> CallableType:
    """Create a type object type based on the signature of __init__."""
    variables = []  # type: List[TypeVarDef]
    variables.extend(info.defn.type_vars)
    variables.extend(init_type.variables)

    callable_type = init_type.copy_modified(
        ret_type=fill_typevars(info), fallback=type_type, name=None, variables=variables,
        special_sig=special_sig)
    c = callable_type.with_name(info.name())
    return c
コード例 #19
0
ファイル: typeanal.py プロジェクト: greatmazinger/mypy
 def visit_callable_type(self, t: CallableType, nested: bool = True) -> Type:
     # Every Callable can bind its own type variables, if they're not in the outer scope
     with self.tvar_scope_frame():
         if self.aliasing:
             variables = t.variables
         else:
             variables = self.bind_function_type_variables(t, t)
         ret = t.copy_modified(arg_types=self.anal_array(t.arg_types, nested=nested),
                               ret_type=self.anal_type(t.ret_type, nested=nested),
                               fallback=t.fallback or self.named_type('builtins.function'),
                               variables=self.anal_var_defs(variables))
     return ret
コード例 #20
0
ファイル: applytype.py プロジェクト: FaithBradley200/mypy
def apply_generic_arguments(callable: CallableType, types: List[Type],
                            msg: MessageBuilder, context: Context) -> Type:
    """Apply generic type arguments to a callable type.

    For example, applying [int] to 'def [T] (T) -> T' results in
    'def [-1:int] (int) -> int'. Here '[-1: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
    if len(tvars) != len(types):
        msg.incompatible_type_application(len(tvars), len(types), context)
        return AnyType()

    # Check that inferred type variable values are compatible with allowed
    # values.  Also, promote subtype values to allowed values.
    types = types[:]
    for i, type in enumerate(types):
        values = callable.variables[i].values
        if values and type:
            if isinstance(type, AnyType):
                continue
            for value in values:
                if mypy.subtypes.is_subtype(type, value):
                    types[i] = value
                    break
            else:
                msg.incompatible_typevar_value(callable, i + 1, type, context)

    # Create a map from type variable id to target type.
    id_to_type = {}  # type: Dict[int, 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.copy_modified(
        arg_types=arg_types,
        ret_type=expand_type(callable.ret_type, id_to_type),
        variables=remaining_tvars,
        bound_vars=callable.bound_vars + bound_vars,
    )
コード例 #21
0
    def get_guesses(self, is_method: bool, base: CallableType, defaults: List[Optional[Type]],
                    callsites: List[Callsite],
                    uses: List[List[Type]]) -> List[CallableType]:
        """Compute a list of guesses for a function's type.

        This focuses just on the argument types, and doesn't change the provided return type.
        """
        options = self.get_args(is_method, base, defaults, callsites, uses)
        options = [self.add_adjustments(tps) for tps in options]

        # Take the first `max_guesses` guesses.
        product = itertools.islice(itertools.product(*options), 0, self.max_guesses)
        return [refine_callable(base, base.copy_modified(arg_types=list(x))) for x in product]
コード例 #22
0
ファイル: applytype.py プロジェクト: yang/mypy-hack
def apply_generic_arguments(callable: CallableType, types: List[Type],
                            msg: MessageBuilder, context: Context) -> Type:
    """Apply generic type arguments to a callable type.

    For example, applying [int] to 'def [T] (T) -> T' results in
    'def [-1:int] (int) -> int'. Here '[-1: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
    if len(tvars) != len(types):
        msg.incompatible_type_application(len(tvars), len(types), context)
        return AnyType()

    # Check that inferred type variable values are compatible with allowed
    # values.  Also, promote subtype values to allowed values.
    types = types[:]
    for i, type in enumerate(types):
        values = callable.variables[i].values
        if values and type:
            if isinstance(type, AnyType):
                continue
            for value in values:
                if mypy.subtypes.is_subtype(type, value):
                    types[i] = value
                    break
            else:
                msg.incompatible_typevar_value(callable, i + 1, type, context)

    # Create a map from type variable id to target type.
    id_to_type = {}  # type: Dict[int, 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.copy_modified(
        arg_types=arg_types,
        ret_type=expand_type(callable.ret_type, id_to_type),
        variables=remaining_tvars,
        bound_vars=callable.bound_vars + bound_vars,
    )
コード例 #23
0
ファイル: checkmember.py プロジェクト: e42s/mypy
def class_callable(init_type: CallableType, info: TypeInfo, type_type: Instance) -> CallableType:
    """Create a type object type based on the signature of __init__."""
    variables = []  # type: List[TypeVarDef]
    for i, tvar in enumerate(info.defn.type_vars):
        variables.append(TypeVarDef(tvar.name, i + 1, tvar.values, tvar.upper_bound,
                                    tvar.variance))

    initvars = init_type.variables
    variables.extend(initvars)

    callable_type = init_type.copy_modified(
        ret_type=self_type(info), fallback=type_type, name=None, variables=variables)
    c = callable_type.with_name('"{}"'.format(info.name()))
    return convert_class_tvars_to_func_tvars(c, len(initvars))
コード例 #24
0
def class_callable(init_type: CallableType, info: TypeInfo, type_type: Instance) -> CallableType:
    """Create a type object type based on the signature of __init__."""
    variables = []  # type: List[TypeVarDef]
    for i, tvar in enumerate(info.defn.type_vars):
        variables.append(TypeVarDef(tvar.name, i + 1, tvar.values, tvar.upper_bound,
                                    tvar.variance))

    initvars = init_type.variables
    variables.extend(initvars)

    callable_type = init_type.copy_modified(
        ret_type=self_type(info), fallback=type_type, name=None, variables=variables)
    c = callable_type.with_name('"{}"'.format(info.name()))
    return convert_class_tvars_to_func_tvars(c, len(initvars))
コード例 #25
0
ファイル: join.py プロジェクト: khlumzeemee/Transcrypt
def combine_similar_callables(t: CallableType, s: CallableType) -> CallableType:
    arg_types = []  # type: List[Type]
    for i in range(len(t.arg_types)):
        arg_types.append(join_types(t.arg_types[i], s.arg_types[i]))
    # TODO kinds and argument names
    # The fallback type can be either 'function' or 'type'. The result should have 'type' as
    # fallback only if both operands have it as 'type'.
    if t.fallback.type.fullname() != 'builtins.type':
        fallback = t.fallback
    else:
        fallback = s.fallback
    return t.copy_modified(arg_types=arg_types,
                           ret_type=join_types(t.ret_type, s.ret_type),
                           fallback=fallback,
                           name=None)
コード例 #26
0
    def visit_callable_type(self, t: CallableType) -> Type:
        param_spec = t.param_spec()
        if param_spec is not None:
            repl = get_proper_type(self.variables.get(param_spec.id))
            # If a ParamSpec in a callable type is substituted with a
            # callable type, we can't use normal substitution logic,
            # since ParamSpec is actually split into two components
            # *P.args and **P.kwargs in the original type. Instead, we
            # must expand both of them with all the argument types,
            # kinds and names in the replacement. The return type in
            # the replacement is ignored.
            if isinstance(repl, CallableType):
                # Substitute *args: P.args, **kwargs: P.kwargs
                t = t.expand_param_spec(repl)
                # TODO: Substitute remaining arg types
                return t.copy_modified(
                    ret_type=t.ret_type.accept(self),
                    type_guard=(t.type_guard.accept(self)
                                if t.type_guard is not None else None))

        return t.copy_modified(arg_types=self.expand_types(t.arg_types),
                               ret_type=t.ret_type.accept(self),
                               type_guard=(t.type_guard.accept(self) if
                                           t.type_guard is not None else None))
コード例 #27
0
ファイル: join.py プロジェクト: FaithBradley200/mypy
def combine_similar_callables(t: CallableType, s: CallableType) -> CallableType:
    arg_types = []  # type: List[Type]
    for i in range(len(t.arg_types)):
        arg_types.append(join_types(t.arg_types[i], s.arg_types[i]))
    # TODO kinds and argument names
    # The fallback type can be either 'function' or 'type'. The result should have 'type' as
    # fallback only if both operands have it as 'type'.
    if t.fallback.type.fullname() != 'builtins.type':
        fallback = t.fallback
    else:
        fallback = s.fallback
    return t.copy_modified(arg_types=arg_types,
                           ret_type=join_types(t.ret_type, s.ret_type),
                           fallback=fallback,
                           name=None)
コード例 #28
0
 def visit_callable_type(self, t: CallableType, nested: bool = True) -> Type:
     # Every Callable can bind its own type variables, if they're not in the outer scope
     with self.tvar_scope_frame():
         if self.defining_alias:
             variables = t.variables
         else:
             variables = self.bind_function_type_variables(t, t)
         ret = t.copy_modified(arg_types=self.anal_array(t.arg_types, nested=nested),
                               ret_type=self.anal_type(t.ret_type, nested=nested),
                               # If the fallback isn't filled in yet,
                               # its type will be the falsey FakeInfo
                               fallback=(t.fallback if t.fallback.type
                                         else self.named_type('builtins.function')),
                               variables=self.anal_var_defs(variables))
     return ret
コード例 #29
0
def meet_similar_callables(t: CallableType, s: CallableType) -> CallableType:
    from mypy.join import join_types
    arg_types = []  # type: List[Type]
    for i in range(len(t.arg_types)):
        arg_types.append(join_types(t.arg_types[i], s.arg_types[i]))
    # TODO in combine_similar_callables also applies here (names and kinds)
    # The fallback type can be either 'function' or 'type'. The result should have 'function' as
    # fallback only if both operands have it as 'function'.
    if t.fallback.type.fullname() != 'builtins.function':
        fallback = t.fallback
    else:
        fallback = s.fallback
    return t.copy_modified(arg_types=arg_types,
                           ret_type=meet_types(t.ret_type, s.ret_type),
                           fallback=fallback,
                           name=None)
コード例 #30
0
ファイル: meet.py プロジェクト: chadrik/mypy
def meet_similar_callables(t: CallableType, s: CallableType) -> CallableType:
    from mypy.join import join_types
    arg_types = []  # type: List[Type]
    for i in range(len(t.arg_types)):
        arg_types.append(join_types(t.arg_types[i], s.arg_types[i]))
    # TODO in combine_similar_callables also applies here (names and kinds)
    # The fallback type can be either 'function' or 'type'. The result should have 'function' as
    # fallback only if both operands have it as 'function'.
    if t.fallback.type.fullname() != 'builtins.function':
        fallback = t.fallback
    else:
        fallback = s.fallback
    return t.copy_modified(arg_types=arg_types,
                           ret_type=meet_types(t.ret_type, s.ret_type),
                           fallback=fallback,
                           name=None)
コード例 #31
0
def class_callable(init_type: CallableType, info: TypeInfo,
                   type_type: Instance, special_sig: Optional[str],
                   is_new: bool) -> CallableType:
    """Create a type object type based on the signature of __init__."""
    variables = []  # type: List[TypeVarDef]
    variables.extend(info.defn.type_vars)
    variables.extend(init_type.variables)

    init_ret_type = get_proper_type(init_type.ret_type)
    if is_new and isinstance(init_ret_type, (Instance, TupleType)):
        ret_type = init_type.ret_type  # type: Type
    else:
        ret_type = fill_typevars(info)

    callable_type = init_type.copy_modified(ret_type=ret_type,
                                            fallback=type_type,
                                            name=None,
                                            variables=variables,
                                            special_sig=special_sig)
    c = callable_type.with_name(info.name())
    return c
コード例 #32
0
ファイル: type_visitor.py プロジェクト: Michael0x2a/mypy
 def visit_callable_type(self, t: CallableType) -> Type:
     return t.copy_modified(arg_types=self.translate_types(t.arg_types),
                            ret_type=t.ret_type.accept(self),
                            variables=self.translate_variables(t.variables))
コード例 #33
0
def update_callable_implicit_bounds(
        t: CallableType, arg_types: List[Tuple[int, Type]]) -> CallableType:
    # FIX what if there are existing bounds?
    return t.copy_modified(bound_vars=arg_types)
コード例 #34
0
ファイル: expandtype.py プロジェクト: lamby/mypy
 def visit_callable_type(self, t: CallableType) -> Type:
     return t.copy_modified(arg_types=self.expand_types(t.arg_types),
                            ret_type=t.ret_type.accept(self))
コード例 #35
0
 def visit_callable_type(self, t: CallableType) -> ProperType:
     return self.copy_common(t, t.copy_modified())
コード例 #36
0
ファイル: expandtype.py プロジェクト: Carreau/mypy
def update_callable_implicit_bounds(
        t: CallableType, arg_types: List[Tuple[int, Type]]) -> CallableType:
    # FIX what if there are existing bounds?
    return t.copy_modified(bound_vars=arg_types)
コード例 #37
0
ファイル: expandtype.py プロジェクト: gnprice/mypy
 def visit_callable_type(self, t: CallableType) -> Type:
     return t.copy_modified(arg_types=self.expand_types(t.arg_types), ret_type=t.ret_type.accept(self))
コード例 #38
0
 def visit_callable_type(self, t: CallableType) -> Type:
     return t.copy_modified(arg_types=self.expand_types(t.arg_types),
                            ret_type=t.ret_type.accept(self),
                            type_guard=(t.type_guard.accept(self)
                                        if t.type_guard is not None else None))
コード例 #39
0
def apply_generic_arguments(callable: CallableType, orig_types: Sequence[Optional[Type]],
                            msg: MessageBuilder, context: Context,
                            skip_unsatisfied: bool = False) -> CallableType:
    """Apply generic type arguments to a callable type.

    For example, applying [int] to 'def [T] (T) -> T' results in
    'def (int) -> int'.

    Note that each type can be None; in this case, it will not be applied.

    If `skip_unsatisfied` is True, then just skip the types that don't satisfy type variable
    bound or constraints, instead of giving an error.
    """
    tvars = callable.variables
    assert len(tvars) == len(orig_types)
    # Check that inferred type variable values are compatible with allowed
    # values and bounds.  Also, promote subtype values to allowed values.
    types = list(orig_types)
    for i, type in enumerate(types):
        assert not isinstance(type, PartialType), "Internal error: must never apply partial type"
        values = callable.variables[i].values
        if type is None:
            continue
        if values:
            if isinstance(type, AnyType):
                continue
            if isinstance(type, TypeVarType) and type.values:
                # Allow substituting T1 for T if every allowed value of T1
                # is also a legal value of T.
                if all(any(is_same_type(v, v1) for v in values)
                       for v1 in type.values):
                    continue
            matching = []
            for value in values:
                if mypy.subtypes.is_subtype(type, value):
                    matching.append(value)
            if matching:
                best = matching[0]
                # If there are more than one matching value, we select the narrowest
                for match in matching[1:]:
                    if mypy.subtypes.is_subtype(match, best):
                        best = match
                types[i] = best
            else:
                if skip_unsatisfied:
                    types[i] = None
                else:
                    msg.incompatible_typevar_value(callable, type, callable.variables[i].name,
                                                   context)
        else:
            upper_bound = callable.variables[i].upper_bound
            if not mypy.subtypes.is_subtype(type, upper_bound):
                if skip_unsatisfied:
                    types[i] = None
                else:
                    msg.incompatible_typevar_value(callable, type, callable.variables[i].name,
                                                   context)

    # Create a map from type variable id to target type.
    id_to_type = {}  # type: Dict[TypeVarId, Type]
    for i, tv in enumerate(tvars):
        typ = types[i]
        if typ:
            id_to_type[tv.id] = typ

    # Apply arguments to argument types.
    arg_types = [expand_type(at, id_to_type) for at in callable.arg_types]

    # 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.copy_modified(
        arg_types=arg_types,
        ret_type=expand_type(callable.ret_type, id_to_type),
        variables=remaining_tvars,
    )
コード例 #40
0
def _check_typeclass_signature(
    typeclass_signature: CallableType,
    instance_signature: CallableType,
    ctx: MethodContext,
) -> bool:
    """
    Checks that instance signature is compatible with.

    We use contravariant on arguments and covariant on return type logic here.
    What does this mean?

    Let's say that you have this typeclass signature:

    .. code:: python

      class A: ...
      class B(A): ...
      class C(B): ...

      @typeclass
      def some(instance, arg: B) -> B: ...

    What instance signatures will be compatible?

    .. code:: python

      (instance: ..., arg: B) -> B: ...
      (instance: ..., arg: A) -> C: ...

    But, any other cases will raise an error.

    .. note::
        We don't check instance types here at all,
        we replace it with ``Any``.
        See special function, where we check instance type.

    """
    simplified_typeclass_signature = typeclass_signature.copy_modified(
        arg_types=[
            AnyType(TypeOfAny.implementation_artifact),
            *typeclass_signature.arg_types[1:],
        ],
    )
    simplified_instance_signature = instance_signature.copy_modified(
        arg_types=[
            AnyType(TypeOfAny.implementation_artifact),
            *instance_signature.arg_types[1:],
        ],
    )
    signature_check = is_subtype(
        simplified_instance_signature,
        simplified_typeclass_signature,
    )
    if not signature_check:
        ctx.api.fail(
            _INCOMPATIBLE_INSTANCE_SIGNATURE_MSG.format(
                instance_signature,
                typeclass_signature.copy_modified(arg_types=[
                    instance_signature.arg_types[0],  # Better error message
                    *typeclass_signature.arg_types[1:],
                ]),
            ),
            ctx.context,
        )
    return signature_check
コード例 #41
0
 def visit_callable_type(self, t: CallableType) -> Type:
     return t.copy_modified(arg_types=self.translate_types(t.arg_types),
                            ret_type=t.ret_type.accept(self),
                            variables=self.translate_variables(t.variables))