Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make messages use builtin types instead of typing's types #15070

Merged
merged 4 commits into from
Apr 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 1 addition & 11 deletions mypy/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,17 +235,7 @@ def _build(

source_set = BuildSourceSet(sources)
cached_read = fscache.read
errors = Errors(
options.show_error_context,
options.show_column_numbers,
options.hide_error_codes,
options.pretty,
options.show_error_end,
lambda path: read_py_file(path, cached_read),
options.show_absolute_path,
options.many_errors_threshold,
options,
)
errors = Errors(options, read_source=lambda path: read_py_file(path, cached_read))
plugin, snapshot = load_plugins(options, errors, stdout, extra_plugins)

# Add catch-all .gitignore to cache dir if we created it
Expand Down
51 changes: 36 additions & 15 deletions mypy/checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@ def __init__(
self.expr_checker = mypy.checkexpr.ExpressionChecker(
self, self.msg, self.plugin, per_line_checking_time_ns
)
self.pattern_checker = PatternChecker(self, self.msg, self.plugin)
self.pattern_checker = PatternChecker(self, self.msg, self.plugin, options)

@property
def type_context(self) -> list[Type | None]:
Expand Down Expand Up @@ -483,7 +483,9 @@ def check_first_pass(self) -> None:
"typing.Sequence", [self.named_type("builtins.str")]
)
if not is_subtype(all_.type, seq_str):
str_seq_s, all_s = format_type_distinctly(seq_str, all_.type)
str_seq_s, all_s = format_type_distinctly(
seq_str, all_.type, options=self.options
)
self.fail(
message_registry.ALL_MUST_BE_SEQ_STR.format(str_seq_s, all_s), all_node
)
Expand Down Expand Up @@ -1178,7 +1180,8 @@ def check_func_def(
msg = None
elif typ.arg_names[i] in {"self", "cls"}:
msg = message_registry.ERASED_SELF_TYPE_NOT_SUPERTYPE.format(
erased, ref_type
erased.str_with_options(self.options),
ref_type.str_with_options(self.options),
)
else:
msg = message_registry.MISSING_OR_INVALID_SELF_TYPE
Expand Down Expand Up @@ -1323,7 +1326,7 @@ def check_unbound_return_typevar(self, typ: CallableType) -> None:
):
self.note(
"Consider using the upper bound "
f"{format_type(typ.ret_type.upper_bound)} instead",
f"{format_type(typ.ret_type.upper_bound, self.options)} instead",
context=typ.ret_type,
)

Expand Down Expand Up @@ -1430,7 +1433,9 @@ def check___new___signature(self, fdef: FuncDef, typ: CallableType) -> None:
get_proper_type(bound_type.ret_type), (AnyType, Instance, TupleType, UninhabitedType)
):
self.fail(
message_registry.NON_INSTANCE_NEW_TYPE.format(format_type(bound_type.ret_type)),
message_registry.NON_INSTANCE_NEW_TYPE.format(
format_type(bound_type.ret_type, self.options)
),
fdef,
)
else:
Expand Down Expand Up @@ -2347,7 +2352,10 @@ class Baz(int, Foo, Bar, enum.Flag): ...
enum_base = base
continue
elif enum_base is not None and not base.type.is_enum:
self.fail(f'No non-enum mixin classes are allowed after "{enum_base}"', defn)
self.fail(
f'No non-enum mixin classes are allowed after "{enum_base.str_with_options(self.options)}"',
defn,
)
break

def check_enum_new(self, defn: ClassDef) -> None:
Expand All @@ -2372,7 +2380,7 @@ def has_new_method(info: TypeInfo) -> bool:
if candidate and has_new:
self.fail(
"Only a single data type mixin is allowed for Enum subtypes, "
'found extra "{}"'.format(base),
'found extra "{}"'.format(base.str_with_options(self.options)),
defn,
)
elif candidate:
Expand Down Expand Up @@ -3974,7 +3982,12 @@ def check_member_assignment(

dunder_set = attribute_type.type.get_method("__set__")
if dunder_set is None:
self.fail(message_registry.DESCRIPTOR_SET_NOT_CALLABLE.format(attribute_type), context)
self.fail(
message_registry.DESCRIPTOR_SET_NOT_CALLABLE.format(
attribute_type.str_with_options(self.options)
),
context,
)
return AnyType(TypeOfAny.from_error), get_type, False

bound_method = analyze_decorator_or_funcbase_access(
Expand Down Expand Up @@ -4128,7 +4141,9 @@ def visit_expression_stmt(self, s: ExpressionStmt) -> None:
if error_note_and_code:
error_note, code = error_note_and_code
self.fail(
message_registry.TYPE_MUST_BE_USED.format(format_type(expr_type)), s, code=code
message_registry.TYPE_MUST_BE_USED.format(format_type(expr_type, self.options)),
s,
code=code,
)
self.note(error_note, s, code=code)

Expand Down Expand Up @@ -4958,7 +4973,9 @@ def _make_fake_typeinfo_and_full_name(
# We use the pretty_names_list for error messages but can't
# use it for the real name that goes into the symbol table
# because it can have dots in it.
pretty_names_list = pretty_seq(format_type_distinctly(*base_classes, bare=True), "and")
pretty_names_list = pretty_seq(
format_type_distinctly(*base_classes, options=self.options, bare=True), "and"
)
try:
info, full_name = _make_fake_typeinfo_and_full_name(base_classes, curr_module)
with self.msg.filter_errors() as local_errors:
Expand Down Expand Up @@ -4995,7 +5012,7 @@ def intersect_instance_callable(self, typ: Instance, callable_type: CallableType
gen_name = gen_unique_name(f"<callable subtype of {typ.type.name}>", cur_module.names)

# Synthesize a fake TypeInfo
short_name = format_type_bare(typ)
short_name = format_type_bare(typ, self.options)
cdef, info = self.make_fake_typeinfo(cur_module.fullname, gen_name, short_name, [typ])

# Build up a fake FuncDef so we can populate the symbol table.
Expand Down Expand Up @@ -5201,7 +5218,7 @@ def _check_for_truthy_type(self, t: Type, expr: Expression) -> None:
return

def format_expr_type() -> str:
typ = format_type(t)
typ = format_type(t, self.options)
if isinstance(expr, MemberExpr):
return f'Member "{expr.name}" has type {typ}'
elif isinstance(expr, RefExpr) and expr.fullname:
Expand All @@ -5216,14 +5233,16 @@ def format_expr_type() -> str:
return f"Expression has type {typ}"

if isinstance(t, FunctionLike):
self.fail(message_registry.FUNCTION_ALWAYS_TRUE.format(format_type(t)), expr)
self.fail(
message_registry.FUNCTION_ALWAYS_TRUE.format(format_type(t, self.options)), expr
)
elif isinstance(t, UnionType):
self.fail(message_registry.TYPE_ALWAYS_TRUE_UNIONTYPE.format(format_expr_type()), expr)
elif isinstance(t, Instance) and t.type.fullname == "typing.Iterable":
_, info = self.make_fake_typeinfo("typing", "Collection", "Collection", [])
self.fail(
message_registry.ITERABLE_ALWAYS_TRUE.format(
format_expr_type(), format_type(Instance(info, t.args))
format_expr_type(), format_type(Instance(info, t.args), self.options)
),
expr,
)
Expand Down Expand Up @@ -6008,7 +6027,9 @@ def check_subtype(
note_msg = ""
notes = notes or []
if subtype_label is not None or supertype_label is not None:
subtype_str, supertype_str = format_type_distinctly(orig_subtype, orig_supertype)
subtype_str, supertype_str = format_type_distinctly(
orig_subtype, orig_supertype, options=self.options
)
if subtype_label is not None:
extra_info.append(subtype_label + " " + subtype_str)
if supertype_label is not None:
Expand Down
14 changes: 12 additions & 2 deletions mypy/checkexpr.py
Original file line number Diff line number Diff line change
Expand Up @@ -3967,7 +3967,12 @@ def visit_type_application(self, tapp: TypeApplication) -> Type:
if isinstance(tapp.expr, RefExpr) and isinstance(tapp.expr.node, TypeAlias):
# Subscription of a (generic) alias in runtime context, expand the alias.
item = expand_type_alias(
tapp.expr.node, tapp.types, self.chk.fail, tapp.expr.node.no_args, tapp
tapp.expr.node,
tapp.types,
self.chk.fail,
tapp.expr.node.no_args,
tapp,
self.chk.options,
)
item = get_proper_type(item)
if isinstance(item, Instance):
Expand Down Expand Up @@ -4032,7 +4037,12 @@ class LongName(Generic[T]): ...
disallow_any = self.chk.options.disallow_any_generics and self.is_callee
item = get_proper_type(
set_any_tvars(
alias, ctx.line, ctx.column, disallow_any=disallow_any, fail=self.msg.fail
alias,
ctx.line,
ctx.column,
self.chk.options,
disallow_any=disallow_any,
fail=self.msg.fail,
)
)
if isinstance(item, Instance):
Expand Down
10 changes: 8 additions & 2 deletions mypy/checkmember.py
Original file line number Diff line number Diff line change
Expand Up @@ -637,7 +637,10 @@ def analyze_descriptor_access(descriptor_type: Type, mx: MemberContext) -> Type:
dunder_get = descriptor_type.type.get_method("__get__")
if dunder_get is None:
mx.msg.fail(
message_registry.DESCRIPTOR_GET_NOT_CALLABLE.format(descriptor_type), mx.context
message_registry.DESCRIPTOR_GET_NOT_CALLABLE.format(
descriptor_type.str_with_options(mx.msg.options)
),
mx.context,
)
return AnyType(TypeOfAny.from_error)

Expand Down Expand Up @@ -694,7 +697,10 @@ def analyze_descriptor_access(descriptor_type: Type, mx: MemberContext) -> Type:

if not isinstance(inferred_dunder_get_type, CallableType):
mx.msg.fail(
message_registry.DESCRIPTOR_GET_NOT_CALLABLE.format(descriptor_type), mx.context
message_registry.DESCRIPTOR_GET_NOT_CALLABLE.format(
descriptor_type.str_with_options(mx.msg.options)
),
mx.context,
)
return AnyType(TypeOfAny.from_error)

Expand Down
24 changes: 19 additions & 5 deletions mypy/checkpattern.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from mypy.meet import narrow_declared_type
from mypy.messages import MessageBuilder
from mypy.nodes import ARG_POS, Context, Expression, NameExpr, TypeAlias, TypeInfo, Var
from mypy.options import Options
from mypy.patterns import (
AsPattern,
ClassPattern,
Expand Down Expand Up @@ -104,7 +105,11 @@ class PatternChecker(PatternVisitor[PatternType]):
# non_sequence_match_type_names
non_sequence_match_types: list[Type]

def __init__(self, chk: mypy.checker.TypeChecker, msg: MessageBuilder, plugin: Plugin) -> None:
options: Options

def __init__(
self, chk: mypy.checker.TypeChecker, msg: MessageBuilder, plugin: Plugin, options: Options
) -> None:
self.chk = chk
self.msg = msg
self.plugin = plugin
Expand All @@ -114,6 +119,7 @@ def __init__(self, chk: mypy.checker.TypeChecker, msg: MessageBuilder, plugin: P
self.non_sequence_match_types = self.generate_types_from_names(
non_sequence_match_type_names
)
self.options = options

def accept(self, o: Pattern, type_context: Type) -> PatternType:
self.type_context.append(type_context)
Expand Down Expand Up @@ -458,8 +464,8 @@ def visit_class_pattern(self, o: ClassPattern) -> PatternType:
elif isinstance(type_info, TypeAlias):
typ = type_info.target
else:
if isinstance(type_info, Var):
name = str(type_info.type)
if isinstance(type_info, Var) and type_info.type is not None:
name = type_info.type.str_with_options(self.options)
else:
name = type_info.name
self.msg.fail(message_registry.CLASS_PATTERN_TYPE_REQUIRED.format(name), o.class_ref)
Expand Down Expand Up @@ -508,7 +514,12 @@ def visit_class_pattern(self, o: ClassPattern) -> PatternType:
)
has_local_errors = local_errors.has_new_errors()
if has_local_errors:
self.msg.fail(message_registry.MISSING_MATCH_ARGS.format(typ), o)
self.msg.fail(
message_registry.MISSING_MATCH_ARGS.format(
typ.str_with_options(self.options)
),
o,
)
return self.early_non_match()

proper_match_args_type = get_proper_type(match_args_type)
Expand Down Expand Up @@ -573,7 +584,10 @@ def visit_class_pattern(self, o: ClassPattern) -> PatternType:
if has_local_errors or key_type is None:
key_type = AnyType(TypeOfAny.from_error)
self.msg.fail(
message_registry.CLASS_PATTERN_UNKNOWN_KEYWORD.format(typ, keyword), pattern
message_registry.CLASS_PATTERN_UNKNOWN_KEYWORD.format(
typ.str_with_options(self.options), keyword
),
pattern,
)

inner_type, inner_rest_type, inner_captures = self.accept(pattern, key_type)
Expand Down
2 changes: 1 addition & 1 deletion mypy/checkstrformat.py
Original file line number Diff line number Diff line change
Expand Up @@ -588,7 +588,7 @@ def apply_field_accessors(
return repl
assert spec.field

temp_errors = Errors()
temp_errors = Errors(self.chk.options)
dummy = DUMMY_FIELD_NAME + spec.field[len(spec.key) :]
temp_ast: Node = parse(
dummy, fnam="<format>", module=None, options=self.chk.options, errors=temp_errors
Expand Down
Loading