def has_no_attr(self, typ: Type, member: str, context: Context) -> Type: """Report a missing or non-accessible member. The type argument is the base type. If member corresponds to an operator, use the corresponding operator name in the messages. Return type Any. """ if (isinstance(typ, Instance) and (cast(Instance, typ)).type.has_readable_member(member)): self.fail('Member "{}" is not assignable'.format(member), context) elif isinstance(typ, Void): self.check_void(typ, context) elif member == '__contains__': self.fail('Unsupported right operand type for in ({})'.format( self.format(typ)), context) elif member in op_methods.values(): # Access to a binary operator member (e.g. _add). This case does # not handle indexing operations. for op, method in op_methods.items(): if method == member: self.unsupported_left_operand(op, typ, context) break elif member == '__neg__': self.fail('Unsupported operand type for unary - ({})'.format( self.format(typ)), context) elif member == '__pos__': self.fail('Unsupported operand type for unary + ({})'.format( self.format(typ)), context) elif member == '__invert__': self.fail('Unsupported operand type for ~ ({})'.format( self.format(typ)), context) elif member == '__getitem__': # Indexed get. self.fail('Value of type {} is not indexable'.format( self.format(typ)), context) elif member == '__setitem__': # Indexed set. self.fail('Unsupported target for indexed assignment', context) elif member == '__call__': self.fail('{} not callable'.format(self.format(typ)), context) else: # The non-special case: a missing ordinary attribute. if not self.disable_type_names: failed = False if isinstance(typ, Instance) and cast(Instance, typ).type.names: typ = cast(Instance, typ) alternatives = set(typ.type.names.keys()) matches = [m for m in COMMON_MISTAKES.get(member, []) if m in alternatives] matches.extend(best_matches(member, alternatives)[:3]) if matches: self.fail('{} has no attribute "{}"; maybe {}?'.format( self.format(typ), member, pretty_or(matches)), context) failed = True if not failed: self.fail('{} has no attribute "{}"'.format(self.format(typ), member), context) else: self.fail('Some element of union has no attribute "{}"'.format( member), context) return AnyType()
def has_no_attr(self, typ: Type, member: str, context: Context) -> Type: """Report a missing or non-accessible member. The type argument is the base type. If member corresponds to an operator, use the corresponding operator name in the messages. Return type Any. """ if (isinstance(typ, Instance) and (cast(Instance, typ)).type.has_readable_member(member)): self.fail('Member "{}" is not assignable'.format(member), context) elif isinstance(typ, Void): self.check_void(typ, context) elif member == '__contains__': self.fail( 'Unsupported right operand type for in ({})'.format( self.format(typ)), context) elif member in op_methods.values(): # Access to a binary operator member (e.g. _add). This case does # not handle indexing operations. for op, method in op_methods.items(): if method == member: self.unsupported_left_operand(op, typ, context) break elif member == '__neg__': self.fail( 'Unsupported operand type for unary - ({})'.format( self.format(typ)), context) elif member == '__invert__': self.fail( 'Unsupported operand type for ~ ({})'.format(self.format(typ)), context) elif member == '__getitem__': # Indexed get. self.fail( 'Value of type {} is not indexable'.format(self.format(typ)), context) elif member == '__setitem__': # Indexed set. self.fail('Unsupported target for indexed assignment', context) else: # The non-special case: a missing ordinary attribute. self.fail( '{} has no attribute "{}"'.format(self.format(typ), member), context) return AnyType()
def has_no_attr(self, typ: Type, member: str, context: Context) -> Type: """Report a missing or non-accessible member. The type argument is the base type. If member corresponds to an operator, use the corresponding operator name in the messages. Return type Any. """ if (isinstance(typ, Instance) and (cast(Instance, typ)).type.has_readable_member(member)): self.fail('Member "{}" is not assignable'.format(member), context) elif isinstance(typ, Void): self.check_void(typ, context) elif member == '__contains__': self.fail('Unsupported right operand type for in ({})'.format( self.format(typ)), context) elif member in op_methods.values(): # Access to a binary operator member (e.g. _add). This case does # not handle indexing operations. for op, method in op_methods.items(): if method == member: self.unsupported_left_operand(op, typ, context) break elif member == '__neg__': self.fail('Unsupported operand type for unary - ({})'.format( self.format(typ)), context) elif member == '__invert__': self.fail('Unsupported operand type for ~ ({})'.format( self.format(typ)), context) elif member == '__getitem__': # Indexed get. self.fail('Value of type {} is not indexable'.format( self.format(typ)), context) elif member == '__setitem__': # Indexed set. self.fail('Unsupported target for indexed assignment', context) else: # The non-special case: a missing ordinary attribute. self.fail('{} has no attribute "{}"'.format(self.format(typ), member), context) return AnyType()
def has_no_attr(self, original_type: Type, typ: Type, member: str, context: Context) -> Type: """Report a missing or non-accessible member. original_type is the top-level type on which the error occurred. typ is the actual type that is missing the member. These can be different, e.g., in a union, original_type will be the union and typ will be the specific item in the union that does not have the member attribute. If member corresponds to an operator, use the corresponding operator name in the messages. Return type Any. """ if (isinstance(original_type, Instance) and original_type.type.has_readable_member(member)): self.fail('Member "{}" is not assignable'.format(member), context) elif member == '__contains__': self.fail('Unsupported right operand type for in ({})'.format( self.format(original_type)), context) elif member in op_methods.values(): # Access to a binary operator member (e.g. _add). This case does # not handle indexing operations. for op, method in op_methods.items(): if method == member: self.unsupported_left_operand(op, original_type, context) break elif member == '__neg__': self.fail('Unsupported operand type for unary - ({})'.format( self.format(original_type)), context) elif member == '__pos__': self.fail('Unsupported operand type for unary + ({})'.format( self.format(original_type)), context) elif member == '__invert__': self.fail('Unsupported operand type for ~ ({})'.format( self.format(original_type)), context) elif member == '__getitem__': # Indexed get. # TODO: Fix this consistently in self.format if isinstance(original_type, CallableType) and original_type.is_type_obj(): self.fail('The type {} is not generic and not indexable'.format( self.format(original_type)), context) else: self.fail('Value of type {} is not indexable'.format( self.format(original_type)), context) elif member == '__setitem__': # Indexed set. self.fail('Unsupported target for indexed assignment', context) elif member == '__call__': if isinstance(original_type, Instance) and \ (original_type.type.fullname() == 'builtins.function'): # "'function' not callable" is a confusing error message. # Explain that the problem is that the type of the function is not known. self.fail('Cannot call function of unknown type', context) else: self.fail('{} not callable'.format(self.format(original_type)), context) else: # The non-special case: a missing ordinary attribute. if not self.disable_type_names: failed = False if isinstance(original_type, Instance) and original_type.type.names: alternatives = set(original_type.type.names.keys()) matches = [m for m in COMMON_MISTAKES.get(member, []) if m in alternatives] matches.extend(best_matches(member, alternatives)[:3]) if matches: self.fail('{} has no attribute "{}"; maybe {}?'.format( self.format(original_type), member, pretty_or(matches)), context) failed = True if not failed: self.fail('{} has no attribute "{}"'.format(self.format(original_type), member), context) elif isinstance(original_type, UnionType): # The checker passes "object" in lieu of "None" for attribute # checks, so we manually convert it back. typ_format = self.format(typ) if typ_format == '"object"' and \ any(type(item) == NoneTyp for item in original_type.items): typ_format = '"None"' self.fail('Item {} of {} has no attribute "{}"'.format( typ_format, self.format(original_type), member), context) return AnyType()
Type has_no_member(self, Type typ, str member, Context context): """Report a missing or non-accessible member. The type argument is the base type. If member corresponds to an operator, use the corresponding operator name in the messages. Return type Any. """ if (isinstance(typ, Instance) and ((Instance)typ).type.has_readable_member(member)): self.fail('Member "{}" is not assignable'.format(member), context) elif isinstance(typ, Void): self.check_void(typ, context) elif member == '__contains__': self.fail('Unsupported right operand type for in ({})'.format( self.format(typ)), context) elif member in op_methods.values(): # Access to a binary operator member (e.g. _add). This case does # not handle indexing operations. for op, method in op_methods.items(): if method == member: self.unsupported_left_operand(op, typ, context) break elif member == '__neg__': self.fail('Unsupported operand type for unary - ({})'.format( self.format(typ)), context) elif member == '__invert__': self.fail('Unsupported operand type for ~ ({})'.format( self.format(typ)), context) elif member == '__getitem__': # Indexed get. self.fail('Value of type {} is not indexable'.format(