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
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)
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)
def analyze_var( name: str, var: Var, itype: Instance, info: TypeInfo, node: Context, is_lvalue: bool, msg: MessageBuilder, not_ready_callback: Callable[[str, Context], None], ) -> Type: """Analyze access to an attribute via a Var node. This is conceptually part of analyze_member_access and the arguments are similar. """ # 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 var.is_initialized_in_class and isinstance(t, FunctionLike): 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 = method_type(functype) if var.is_property: # A property cannot have an overloaded type => the cast # is fine. return cast(CallableType, signature).ret_type else: return signature return t else: if not var.is_ready: not_ready_callback(var.name(), node) # Implicit 'Any' type. return AnyType()
def analyze_var(name: str, var: Var, itype: Instance, info: TypeInfo, node: Context, is_lvalue: bool, msg: MessageBuilder, not_ready_callback: Callable[[str, Context], None]) -> Type: """Analyze access to an attribute via a Var node. This is conceptually part of analyze_member_access and the arguments are similar. """ # 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 var.is_initialized_in_class and isinstance(t, FunctionLike): 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 = method_type(functype) if var.is_property: # A property cannot have an overloaded type => the cast # is fine. return cast(CallableType, signature).ret_type else: return signature return t else: if not var.is_ready: not_ready_callback(var.name(), node) # Implicit 'Any' type. return AnyType()
def analyze_var( name: str, var: Var, itype: Instance, info: TypeInfo, node: Context, is_lvalue: bool, msg: MessageBuilder ) -> Type: """Analyze access to an attribute via a Var node. This is conceptually part of analyze_member_access and the arguments are similar. """ # Found a member variable. 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: 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 = 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(CallableType, 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()
def analyze_var(name: str, var: Var, itype: Instance, info: TypeInfo, node: Context, is_lvalue: bool, msg: MessageBuilder) -> Type: """Analyze access to an attribute via a Var node. This is conceptually part of analyze_member_access and the arguments are similar. """ # Found a member variable. 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: 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 = 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(CallableType, 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()
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
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