Exemple #1
0
def analyze_var(name: str, var: Var, itype: Instance, info: TypeInfo,
                node: Context, is_lvalue: bool, msg: MessageBuilder,
                original_type: Type,
                not_ready_callback: Callable[[str, Context], None], *,
                chk: 'mypy.checker.TypeChecker') -> Type:
    """Analyze access to an attribute via a Var node.

    This is conceptually part of analyze_member_access and the arguments are similar.

    original_type is the type of E in the expression E.var
    """
    # Found a member variable.
    itype = map_instance_to_supertype(itype, var.info)
    typ = var.type
    if typ:
        if isinstance(typ, PartialType):
            return handle_partial_attribute_type(typ, is_lvalue, msg, var)
        t = expand_type_by_instance(typ, itype)
        if is_lvalue and var.is_property and not var.is_settable_property:
            # TODO allow setting attributes in subclass (although it is probably an error)
            msg.read_only_property(name, info, node)
        if is_lvalue and var.is_classvar:
            msg.cant_assign_to_classvar(name, node)
        result = t
        if var.is_initialized_in_class and isinstance(
                t, FunctionLike) and not t.is_type_obj():
            if is_lvalue:
                if var.is_property:
                    if not var.is_settable_property:
                        msg.read_only_property(name, info, node)
                else:
                    msg.cant_assign_to_method(node)

            if not var.is_staticmethod:
                # Class-level function objects and classmethods become bound
                # methods: the former to the instance, the latter to the
                # class.
                functype = t
                check_method_type(functype, itype, var.is_classmethod, node,
                                  msg)
                signature = bind_self(functype, original_type,
                                      var.is_classmethod)
                if var.is_property:
                    # A property cannot have an overloaded type => the cast
                    # is fine.
                    assert isinstance(signature, CallableType)
                    result = signature.ret_type
                else:
                    result = signature
    else:
        if not var.is_ready:
            not_ready_callback(var.name(), node)
        # Implicit 'Any' type.
        result = AnyType(TypeOfAny.special_form)
    fullname = '{}.{}'.format(var.info.fullname(), name)
    hook = chk.plugin.get_attribute_hook(fullname)
    if hook:
        result = hook(AttributeContext(original_type, result, node, chk))
    return result
Exemple #2
0
def analyze_var(name: str, var: Var, itype: Instance, info: TypeInfo,
                node: Context, is_lvalue: bool, msg: MessageBuilder,
                original_type: Type,
                not_ready_callback: Callable[[str, Context], None], *,
                chk: 'mypy.checker.TypeChecker') -> Type:
    """Analyze access to an attribute via a Var node.

    This is conceptually part of analyze_member_access and the arguments are similar.

    itype is the class object in which var is dedined
    original_type is the type of E in the expression E.var
    """
    # Found a member variable.
    itype = map_instance_to_supertype(itype, var.info)
    typ = var.type
    if typ:
        if isinstance(typ, PartialType):
            return handle_partial_attribute_type(typ, is_lvalue, msg, var)
        t = expand_type_by_instance(typ, itype)
        if is_lvalue and var.is_property and not var.is_settable_property:
            # TODO allow setting attributes in subclass (although it is probably an error)
            msg.read_only_property(name, info, node)
        if is_lvalue and var.is_classvar:
            msg.cant_assign_to_classvar(name, node)
        result = t
        if var.is_initialized_in_class and isinstance(
                t, FunctionLike) and not t.is_type_obj():
            if is_lvalue:
                if var.is_property:
                    if not var.is_settable_property:
                        msg.read_only_property(name, info, node)
                else:
                    msg.cant_assign_to_method(node)

            if not var.is_staticmethod:
                # Class-level function objects and classmethods become bound methods:
                # the former to the instance, the latter to the class.
                functype = t
                # Use meet to narrow original_type to the dispatched type.
                # For example, assume
                # * A.f: Callable[[A1], None] where A1 <: A (maybe A1 == A)
                # * B.f: Callable[[B1], None] where B1 <: B (maybe B1 == B)
                # * x: Union[A1, B1]
                # In `x.f`, when checking `x` against A1 we assume x is compatible with A
                # and similarly for B1 when checking agains B
                dispatched_type = meet.meet_types(original_type, itype)
                check_self_arg(functype, dispatched_type, var.is_classmethod,
                               node, name, msg)
                signature = bind_self(functype, original_type,
                                      var.is_classmethod)
                if var.is_property:
                    # A property cannot have an overloaded type => the cast is fine.
                    assert isinstance(signature, CallableType)
                    result = signature.ret_type
                else:
                    result = signature
    else:
        if not var.is_ready:
            not_ready_callback(var.name(), node)
        # Implicit 'Any' type.
        result = AnyType(TypeOfAny.special_form)
    fullname = '{}.{}'.format(var.info.fullname(), name)
    hook = chk.plugin.get_attribute_hook(fullname)
    if hook:
        result = hook(AttributeContext(original_type, result, node, chk))
    return result
Exemple #3
0
def analyze_var(name: str, var: Var, itype: Instance, info: TypeInfo, node: Context,
                is_lvalue: bool, msg: MessageBuilder, original_type: Type,
                not_ready_callback: Callable[[str, Context], None], *,
                chk: 'mypy.checker.TypeChecker') -> Type:
    """Analyze access to an attribute via a Var node.

    This is conceptually part of analyze_member_access and the arguments are similar.

    itype is the class object in which var is dedined
    original_type is the type of E in the expression E.var
    """
    # Found a member variable.
    itype = map_instance_to_supertype(itype, var.info)
    typ = var.type
    if typ:
        if isinstance(typ, PartialType):
            return handle_partial_attribute_type(typ, is_lvalue, msg, var)
        t = expand_type_by_instance(typ, itype)
        if is_lvalue and var.is_property and not var.is_settable_property:
            # TODO allow setting attributes in subclass (although it is probably an error)
            msg.read_only_property(name, info, node)
        if is_lvalue and var.is_classvar:
            msg.cant_assign_to_classvar(name, node)
        result = t
        if var.is_initialized_in_class and isinstance(t, FunctionLike) and not t.is_type_obj():
            if is_lvalue:
                if var.is_property:
                    if not var.is_settable_property:
                        msg.read_only_property(name, info, node)
                else:
                    msg.cant_assign_to_method(node)

            if not var.is_staticmethod:
                # Class-level function objects and classmethods become bound methods:
                # the former to the instance, the latter to the class.
                functype = t
                # Use meet to narrow original_type to the dispatched type.
                # For example, assume
                # * A.f: Callable[[A1], None] where A1 <: A (maybe A1 == A)
                # * B.f: Callable[[B1], None] where B1 <: B (maybe B1 == B)
                # * x: Union[A1, B1]
                # In `x.f`, when checking `x` against A1 we assume x is compatible with A
                # and similarly for B1 when checking agains B
                dispatched_type = meet.meet_types(original_type, itype)
                check_self_arg(functype, dispatched_type, var.is_classmethod, node, name, msg)
                signature = bind_self(functype, original_type, var.is_classmethod)
                if var.is_property:
                    # A property cannot have an overloaded type => the cast is fine.
                    assert isinstance(signature, CallableType)
                    result = signature.ret_type
                else:
                    result = signature
    else:
        if not var.is_ready:
            not_ready_callback(var.name(), node)
        # Implicit 'Any' type.
        result = AnyType(TypeOfAny.special_form)
    fullname = '{}.{}'.format(var.info.fullname(), name)
    hook = chk.plugin.get_attribute_hook(fullname)
    if hook:
        result = hook(AttributeContext(original_type, result, node, chk))
    return result