コード例 #1
0
ファイル: checkmember.py プロジェクト: catherine244/Reviews
def check_self_arg(functype: FunctionLike,
                   dispatched_arg_type: Type,
                   is_classmethod: bool,
                   context: Context, name: str,
                   msg: MessageBuilder) -> None:
    """For x.f where A.f: A1 -> T, check that meet(type(x), A) <: A1 for each overload.

    dispatched_arg_type is meet(B, A) in the following example

        def g(x: B): x.f
        class A:
            f: Callable[[A1], None]
    """
    # TODO: this is too strict. We can return filtered overloads for matching definitions
    for item in functype.items():
        if not item.arg_types or item.arg_kinds[0] not in (ARG_POS, ARG_STAR):
            # No positional first (self) argument (*args is okay).
            msg.no_formal_self(name, item, context)
        else:
            selfarg = item.arg_types[0]
            if is_classmethod:
                dispatched_arg_type = TypeType.make_normalized(dispatched_arg_type)
            if not subtypes.is_subtype(dispatched_arg_type, erase_to_bound(selfarg)):
                msg.incompatible_self_argument(name, dispatched_arg_type, item,
                                               is_classmethod, context)
コード例 #2
0
ファイル: visitor.py プロジェクト: thepabloaguilar/returns
def _process_kinded_type(kind: Instance) -> Type:
    """Recursively process all type arguments in a kind."""
    if not kind.args:
        return kind

    real_type = get_proper_type(kind.args[0])
    if isinstance(real_type, TypeVarType):
        return erase_to_bound(real_type)
    elif isinstance(real_type, Instance):
        return real_type.copy_modified(args=kind.args[1:len(real_type.args) +
                                                      1], )

    # This should never happen, probably can be an exception:
    return AnyType(TypeOfAny.implementation_artifact)
コード例 #3
0
ファイル: checkmember.py プロジェクト: matthewrv/mypy
def check_self_arg(functype: FunctionLike,
                   dispatched_arg_type: Type,
                   is_classmethod: bool,
                   context: Context, name: str,
                   msg: MessageBuilder) -> FunctionLike:
    """Check that an instance has a valid type for a method with annotated 'self'.

    For example if the method is defined as:
        class A:
            def f(self: S) -> T: ...
    then for 'x.f' we check that meet(type(x), A) <: S. If the method is overloaded, we
    select only overloads items that satisfy this requirement. If there are no matching
    overloads, an error is generated.

    Note: dispatched_arg_type uses a meet to select a relevant item in case if the
    original type of 'x' is a union. This is done because several special methods
    treat union types in ad-hoc manner, so we can't use MemberContext.self_type yet.
    """
    items = functype.items
    if not items:
        return functype
    new_items = []
    if is_classmethod:
        dispatched_arg_type = TypeType.make_normalized(dispatched_arg_type)
    for item in items:
        if not item.arg_types or item.arg_kinds[0] not in (ARG_POS, ARG_STAR):
            # No positional first (self) argument (*args is okay).
            msg.no_formal_self(name, item, context)
            # This is pretty bad, so just return the original signature if
            # there is at least one such error.
            return functype
        else:
            selfarg = item.arg_types[0]
            if subtypes.is_subtype(dispatched_arg_type, erase_typevars(erase_to_bound(selfarg))):
                new_items.append(item)
            elif isinstance(selfarg, ParamSpecType):
                # TODO: This is not always right. What's the most reasonable thing to do here?
                new_items.append(item)
    if not new_items:
        # Choose first item for the message (it may be not very helpful for overloads).
        msg.incompatible_self_argument(name, dispatched_arg_type, items[0],
                                       is_classmethod, context)
        return functype
    if len(new_items) == 1:
        return new_items[0]
    return Overloaded(new_items)
コード例 #4
0
def debound(ctx: FunctionContext) -> MypyType:
    """
    Analyzes the proper return type of ``debound`` function.

    Uses the ``upper_bound`` of ``TypeVar`` to infer the type of a ``Kind``.

    Here's a quick example:

    .. code:: python

      from typing import TypeVar
      from returns.primitives.hkt import Kind1, debound
      from returns.interfaces import Bindable1

      B = TypeVar('B', bound=Bindable1)

      x: Kind1[B, int]
      instance, rebound = debound(x)
      reveal_type(instance)  # Revealed type: 'Bindable[int]'

    See :func:`returns.primitives.hkt.debound` for more information.

    """
    if not isinstance(ctx.default_return_type, TupleType):
        return AnyType(TypeOfAny.from_error)
    if not ctx.arg_types or not ctx.arg_types[0][0]:
        return AnyType(TypeOfAny.from_error)

    kind = cast(Instance, ctx.arg_types[0][0])
    typevar = kind.args[0]
    if not isinstance(typevar, TypeVarType):
        ctx.api.fail(_KindErrors.debound_not_typevar, ctx.context)
        return AnyType(TypeOfAny.from_error)

    bound = get_proper_type(erase_to_bound(typevar))
    if not isinstance(bound, Instance):
        ctx.api.fail(_KindErrors.debound_not_typevar, ctx.context)
        return AnyType(TypeOfAny.from_error)

    instance = bound.copy_modified(args=kind.args[1:])
    return ctx.default_return_type.copy_modified(
        items=[instance, ctx.default_return_type.items[1]], )
コード例 #5
0
def _process_kinded_type(kind: MypyType) -> MypyType:
    """Recursively process all type arguments in a kind."""
    kind = get_proper_type(kind)
    if not isinstance(kind, Instance) or not kind.args:
        return kind

    real_type = kind.args[0]
    if isinstance(real_type, TypeVarType):
        return erase_to_bound(real_type)

    real_type = get_proper_type(real_type)
    if isinstance(real_type, Instance):
        return real_type.copy_modified(args=[
            # Let's check if there are any nested `KindN[]` instance,
            # if so, it would be dekinded into a regular type following
            # the same rules:
            _process_kinded_type(type_arg)
            for type_arg in kind.args[1:len(real_type.args) + 1]
        ])
    return kind
コード例 #6
0
def _process_kinded_type(instance: MypyType) -> MypyType:
    """Recursively process all type arguments in a kind."""
    kind = get_proper_type(instance)
    if not isinstance(kind, Instance) or not kind.args:
        return instance

    if kind.type.fullname != TYPED_KINDN:  # this is some other instance
        return instance

    real_type = get_proper_type(kind.args[0])
    if isinstance(real_type, TypeVarType):
        return erase_to_bound(real_type)
    elif isinstance(real_type, Instance):
        return real_type.copy_modified(args=[
            # Let's check if there are any nested `KindN[]` instance,
            # if so, it would be dekinded into a regular type following
            # the same rules:
            _process_kinded_type(type_arg)
            for type_arg in kind.args[1:len(real_type.args) + 1]
        ])
    # This should never happen, probably can be an exception:
    return AnyType(TypeOfAny.implementation_artifact)