Exemplo n.º 1
0
def analyze_member_var_access(name: str,
                              itype: Instance,
                              info: TypeInfo,
                              node: Context,
                              is_lvalue: bool,
                              is_super: bool,
                              builtin_type: Callable[[str], Instance],
                              not_ready_callback: Callable[[str, Context],
                                                           None],
                              msg: MessageBuilder,
                              original_type: Type,
                              chk: 'mypy.checker.TypeChecker' = None) -> Type:
    """Analyse attribute access that does not target a method.

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

    original_type is the type of E in the expression E.var
    """
    # It was not a method. Try looking up a variable.
    v = lookup_member_var_or_accessor(info, name, is_lvalue)

    vv = v
    if isinstance(vv, Decorator):
        # The associated Var node of a decorator contains the type.
        v = vv.var

    if isinstance(v, Var):
        return analyze_var(name, v, itype, info, node, is_lvalue, msg,
                           original_type, not_ready_callback)
    elif isinstance(v, FuncDef):
        assert False, "Did not expect a function"
    elif not v and name not in [
            '__getattr__', '__setattr__', '__getattribute__'
    ]:
        if not is_lvalue:
            for method_name in ('__getattribute__', '__getattr__'):
                method = info.get_method(method_name)
                # __getattribute__ is defined on builtins.object and returns Any, so without
                # the guard this search will always find object.__getattribute__ and conclude
                # that the attribute exists
                if method and method.info.fullname() != 'builtins.object':
                    function = function_type(method,
                                             builtin_type('builtins.function'))
                    bound_method = bind_self(function, original_type)
                    typ = map_instance_to_supertype(itype, method.info)
                    getattr_type = expand_type_by_instance(bound_method, typ)
                    if isinstance(getattr_type, CallableType):
                        return getattr_type.ret_type

    if itype.type.fallback_to_any:
        return AnyType()

    # Could not find the member.
    if is_super:
        msg.undefined_in_superclass(name, node)
        return AnyType()
    else:
        if chk and chk.should_suppress_optional_error([itype]):
            return AnyType()
        return msg.has_no_attr(original_type, name, node)
Exemplo n.º 2
0
def analyse_member_var_access(name: str, itype: Instance, info: TypeInfo,
                              node: Context, is_lvalue: bool, is_super: bool,
                              msg: MessageBuilder,
                              report_type: Type = None) -> Type:
    """Analyse attribute access that does not target a method.

    This is logically part of analyse_member_access and the arguments are
    similar.
    """
    # It was not a method. Try looking up a variable.
    v = lookup_member_var_or_accessor(info, name, is_lvalue)

    vv = v
    if isinstance(vv, Decorator):
        # The associated Var node of a decorator contains the type.
        v = vv.var

    if isinstance(v, Var):
        # Found a member variable.
        var = v
        itype = map_instance_to_supertype(itype, var.info)
        if var.type:
            t = expand_type_by_instance(var.type, itype)
            if var.is_initialized_in_class and isinstance(t, FunctionLike):
                if is_lvalue:
                    if var.is_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 = cast(FunctionLike, t)
                    check_method_type(functype, itype, node, msg)
                    signature = method_type(functype)
                    if var.is_property:
                        # A property cannot have an overloaded type => the cast
                        # is fine.
                        return cast(Callable, signature).ret_type
                    else:
                        return signature
            return t
        else:
            if not var.is_ready:
                msg.cannot_determine_type(var.name(), node)
            # Implicit 'Any' type.
            return AnyType()
    elif isinstance(v, FuncDef):
        assert False, "Did not expect a function"

    # Could not find the member.
    if is_super:
        msg.undefined_in_superclass(name, node)
        return AnyType()
    else:
        return msg.has_no_attr(report_type or itype, name, node)
Exemplo n.º 3
0
def analyse_member_var_access(name: str,
                              itype: Instance,
                              info: TypeInfo,
                              node: Context,
                              is_lvalue: bool,
                              is_super: bool,
                              msg: MessageBuilder,
                              report_type: Type = None) -> Type:
    """Analyse attribute access that does not target a method.

    This is logically part of analyse_member_access and the arguments are
    similar.
    """
    # It was not a method. Try looking up a variable.
    v = lookup_member_var_or_accessor(info, name, is_lvalue)

    vv = v
    if isinstance(vv, Decorator):
        # The associated Var node of a decorator contains the type.
        v = vv.var

    if isinstance(v, Var):
        # Found a member variable.
        var = v
        itype = map_instance_to_supertype(itype, var.info)
        if var.type:
            t = expand_type_by_instance(var.type, itype)
            if (var.is_initialized_in_class and isinstance(t, FunctionLike)
                    and not var.is_staticmethod):
                # Class-level function object becomes a bound method.
                functype = cast(FunctionLike, t)
                check_method_type(functype, itype, node, msg)
                signature = method_type(functype)
                if var.is_property:
                    if is_lvalue:
                        msg.read_only_property(name, info, node)
                    # A property cannot have an overloaded type => the cast
                    # is fine.
                    return cast(Callable, signature).ret_type
                else:
                    return signature
            return t
        else:
            if not var.is_ready:
                msg.cannot_determine_type(var.name(), node)
            # Implicit 'Any' type.
            return AnyType()
    elif isinstance(v, FuncDef):
        assert False, "Did not expect a function"

    # Could not find the member.
    if is_super:
        msg.undefined_in_superclass(name, node)
        return AnyType()
    else:
        return msg.has_no_attr(report_type or itype, name, node)
Exemplo n.º 4
0
def analyze_member_var_access(name: str, itype: Instance, info: TypeInfo,
                              node: Context, is_lvalue: bool, is_super: bool,
                              builtin_type: Callable[[str], Instance],
                              not_ready_callback: Callable[[str, Context], None],
                              msg: MessageBuilder,
                              original_type: Type,
                              chk: 'mypy.checker.TypeChecker' = None) -> Type:
    """Analyse attribute access that does not target a method.

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

    original_type is the type of E in the expression E.var
    """
    # It was not a method. Try looking up a variable.
    v = lookup_member_var_or_accessor(info, name, is_lvalue)

    vv = v
    if isinstance(vv, Decorator):
        # The associated Var node of a decorator contains the type.
        v = vv.var

    if isinstance(v, Var):
        return analyze_var(name, v, itype, info, node, is_lvalue, msg,
                           original_type, not_ready_callback)
    elif isinstance(v, FuncDef):
        assert False, "Did not expect a function"
    elif not v and name not in ['__getattr__', '__setattr__', '__getattribute__']:
        if not is_lvalue:
            for method_name in ('__getattribute__', '__getattr__'):
                method = info.get_method(method_name)
                # __getattribute__ is defined on builtins.object and returns Any, so without
                # the guard this search will always find object.__getattribute__ and conclude
                # that the attribute exists
                if method and method.info.fullname() != 'builtins.object':
                    function = function_type(method, builtin_type('builtins.function'))
                    bound_method = bind_self(function, original_type)
                    typ = map_instance_to_supertype(itype, method.info)
                    getattr_type = expand_type_by_instance(bound_method, typ)
                    if isinstance(getattr_type, CallableType):
                        return getattr_type.ret_type

    if itype.type.fallback_to_any:
        return AnyType()

    # Could not find the member.
    if is_super:
        msg.undefined_in_superclass(name, node)
        return AnyType()
    else:
        if chk and chk.should_suppress_optional_error([itype]):
            return AnyType()
        return msg.has_no_attr(original_type, name, node)
Exemplo n.º 5
0
def analyze_member_var_access(
    name: str,
    itype: Instance,
    info: TypeInfo,
    node: Context,
    is_lvalue: bool,
    is_super: bool,
    builtin_type: Callable[[str], Instance],
    not_ready_callback: Callable[[str, Context], None],
    msg: MessageBuilder,
    report_type: Type = None,
    chk: "mypy.checker.TypeChecker" = None,
) -> Type:
    """Analyse attribute access that does not target a method.

    This is logically part of analyze_member_access and the arguments are
    similar.
    """
    # It was not a method. Try looking up a variable.
    v = lookup_member_var_or_accessor(info, name, is_lvalue)

    vv = v
    if isinstance(vv, Decorator):
        # The associated Var node of a decorator contains the type.
        v = vv.var
    if isinstance(v, Var):
        return analyze_var(name, v, itype, info, node, is_lvalue, msg, not_ready_callback)
    elif isinstance(v, FuncDef):
        assert False, "Did not expect a function"
    elif not v and name not in ["__getattr__", "__setattr__"]:
        if not is_lvalue:
            method = info.get_method("__getattr__")
            if method:
                typ = map_instance_to_supertype(itype, method.info)
                getattr_type = expand_type_by_instance(
                    method_type_with_fallback(method, builtin_type("builtins.function")), typ
                )
                if isinstance(getattr_type, CallableType):
                    return getattr_type.ret_type

    if itype.type.fallback_to_any:
        return AnyType()

    # Could not find the member.
    if is_super:
        msg.undefined_in_superclass(name, node)
        return AnyType()
    else:
        if chk and chk.should_suppress_optional_error([itype]):
            return AnyType()
        return msg.has_no_attr(report_type or itype, name, node)
Exemplo n.º 6
0
def analyze_member_var_access(name: str,
                              itype: Instance,
                              info: TypeInfo,
                              node: Context,
                              is_lvalue: bool,
                              is_super: bool,
                              builtin_type: Callable[[str], Instance],
                              not_ready_callback: Callable[[str, Context],
                                                           None],
                              msg: MessageBuilder,
                              report_type: Type = None,
                              chk: 'mypy.checker.TypeChecker' = None) -> Type:
    """Analyse attribute access that does not target a method.

    This is logically part of analyze_member_access and the arguments are
    similar.
    """
    # It was not a method. Try looking up a variable.
    v = lookup_member_var_or_accessor(info, name, is_lvalue)

    vv = v
    if isinstance(vv, Decorator):
        # The associated Var node of a decorator contains the type.
        v = vv.var
    if isinstance(v, Var):
        return analyze_var(name, v, itype, info, node, is_lvalue, msg,
                           not_ready_callback)
    elif isinstance(v, FuncDef):
        assert False, "Did not expect a function"
    elif not v and name not in ['__getattr__', '__setattr__']:
        if not is_lvalue:
            method = info.get_method('__getattr__')
            if method:
                typ = map_instance_to_supertype(itype, method.info)
                getattr_type = expand_type_by_instance(
                    method_type_with_fallback(
                        method, builtin_type('builtins.function')), typ)
                if isinstance(getattr_type, CallableType):
                    return getattr_type.ret_type

    if itype.type.fallback_to_any:
        return AnyType()

    # Could not find the member.
    if is_super:
        msg.undefined_in_superclass(name, node)
        return AnyType()
    else:
        if chk and chk.should_suppress_optional_error([itype]):
            return AnyType()
        return msg.has_no_attr(report_type or itype, name, node)
Exemplo n.º 7
0
def analyze_member_var_access(name: str, itype: Instance, info: TypeInfo,
                              node: Context, is_lvalue: bool, is_super: bool,
                              builtin_type: Callable[[str], Instance],
                              not_ready_callback: Callable[[str, Context], None],
                              msg: MessageBuilder,
                              original_type: Type,
                              chk: 'mypy.checker.TypeChecker') -> Type:
    """Analyse attribute access that does not target a method.

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

    original_type is the type of E in the expression E.var
    """
    # It was not a method. Try looking up a variable.
    v = lookup_member_var_or_accessor(info, name, is_lvalue)

    vv = v
    if isinstance(vv, Decorator):
        # The associated Var node of a decorator contains the type.
        v = vv.var

    if isinstance(vv, TypeInfo):
        # If the associated variable is a TypeInfo synthesize a Var node for
        # the purposes of type checking.  This enables us to type check things
        # like accessing class attributes on an inner class.
        v = Var(name, type=type_object_type(vv, builtin_type))
        v.info = info

    if isinstance(vv, TypeAlias) and isinstance(vv.target, Instance):
        # Similar to the above TypeInfo case, we allow using
        # qualified type aliases in runtime context if it refers to an
        # instance type. For example:
        #     class C:
        #         A = List[int]
        #     x = C.A() <- this is OK
        typ = instance_alias_type(vv, builtin_type)
        v = Var(name, type=typ)
        v.info = info

    if isinstance(v, Var):
        implicit = info[name].implicit

        # An assignment to final attribute is always an error,
        # independently of types.
        if is_lvalue and not chk.get_final_context():
            check_final_member(name, info, msg, node)

        return analyze_var(name, v, itype, info, node, is_lvalue, msg,
                           original_type, builtin_type, not_ready_callback,
                           chk=chk, implicit=implicit)
    elif isinstance(v, FuncDef):
        assert False, "Did not expect a function"
    elif not v and name not in ['__getattr__', '__setattr__', '__getattribute__']:
        if not is_lvalue:
            for method_name in ('__getattribute__', '__getattr__'):
                method = info.get_method(method_name)
                # __getattribute__ is defined on builtins.object and returns Any, so without
                # the guard this search will always find object.__getattribute__ and conclude
                # that the attribute exists
                if method and method.info.fullname() != 'builtins.object':
                    function = function_type(method, builtin_type('builtins.function'))
                    bound_method = bind_self(function, original_type)
                    typ = map_instance_to_supertype(itype, method.info)
                    getattr_type = expand_type_by_instance(bound_method, typ)
                    if isinstance(getattr_type, CallableType):
                        return getattr_type.ret_type
        else:
            setattr_meth = info.get_method('__setattr__')
            if setattr_meth and setattr_meth.info.fullname() != 'builtins.object':
                setattr_func = function_type(setattr_meth, builtin_type('builtins.function'))
                bound_type = bind_self(setattr_func, original_type)
                typ = map_instance_to_supertype(itype, setattr_meth.info)
                setattr_type = expand_type_by_instance(bound_type, typ)
                if isinstance(setattr_type, CallableType) and len(setattr_type.arg_types) > 0:
                    return setattr_type.arg_types[-1]

    if itype.type.fallback_to_any:
        return AnyType(TypeOfAny.special_form)

    # Could not find the member.
    if is_super:
        msg.undefined_in_superclass(name, node)
        return AnyType(TypeOfAny.from_error)
    else:
        if chk and chk.should_suppress_optional_error([itype]):
            return AnyType(TypeOfAny.from_error)
        return msg.has_no_attr(original_type, itype, name, node)