Skip to content

Commit 857c624

Browse files
committed
Merge remote-tracking branch 'origin/master' into 2023-04-13-attrs-evolve-union
2 parents b6233fb + 0845818 commit 857c624

File tree

113 files changed

+1324
-596
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

113 files changed

+1324
-596
lines changed

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
repos:
22
- repo: https://github.com/psf/black
3-
rev: 22.12.0 # must match test-requirements.txt
3+
rev: 23.3.0 # must match test-requirements.txt
44
hooks:
55
- id: black
66
- repo: https://github.com/pycqa/isort

misc/analyze_cache.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ def load_json(data_path: str, meta_path: str) -> CacheData:
6262

6363

6464
def get_files(root: str) -> Iterable[CacheData]:
65-
for (dirpath, dirnames, filenames) in os.walk(root):
65+
for dirpath, dirnames, filenames in os.walk(root):
6666
for filename in filenames:
6767
if filename.endswith(".data.json"):
6868
meta_filename = filename.replace(".data.json", ".meta.json")

misc/fix_annotate.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ def foo(self, bar, baz=12):
3838

3939

4040
class FixAnnotate(BaseFix):
41-
4241
# This fixer is compatible with the bottom matcher.
4342
BM_compatible = True
4443

mypy/api.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@
5151

5252

5353
def _run(main_wrapper: Callable[[TextIO, TextIO], None]) -> tuple[str, str, int]:
54-
5554
stdout = StringIO()
5655
stderr = StringIO()
5756

mypy/build.py

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -235,17 +235,7 @@ def _build(
235235

236236
source_set = BuildSourceSet(sources)
237237
cached_read = fscache.read
238-
errors = Errors(
239-
options.show_error_context,
240-
options.show_column_numbers,
241-
options.hide_error_codes,
242-
options.pretty,
243-
options.show_error_end,
244-
lambda path: read_py_file(path, cached_read),
245-
options.show_absolute_path,
246-
options.many_errors_threshold,
247-
options,
248-
)
238+
errors = Errors(options, read_source=lambda path: read_py_file(path, cached_read))
249239
plugin, snapshot = load_plugins(options, errors, stdout, extra_plugins)
250240

251241
# Add catch-all .gitignore to cache dir if we created it

mypy/checker.py

Lines changed: 45 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -419,7 +419,7 @@ def __init__(
419419
self.expr_checker = mypy.checkexpr.ExpressionChecker(
420420
self, self.msg, self.plugin, per_line_checking_time_ns
421421
)
422-
self.pattern_checker = PatternChecker(self, self.msg, self.plugin)
422+
self.pattern_checker = PatternChecker(self, self.msg, self.plugin, options)
423423

424424
@property
425425
def type_context(self) -> list[Type | None]:
@@ -483,7 +483,9 @@ def check_first_pass(self) -> None:
483483
"typing.Sequence", [self.named_type("builtins.str")]
484484
)
485485
if not is_subtype(all_.type, seq_str):
486-
str_seq_s, all_s = format_type_distinctly(seq_str, all_.type)
486+
str_seq_s, all_s = format_type_distinctly(
487+
seq_str, all_.type, options=self.options
488+
)
487489
self.fail(
488490
message_registry.ALL_MUST_BE_SEQ_STR.format(str_seq_s, all_s), all_node
489491
)
@@ -1178,7 +1180,8 @@ def check_func_def(
11781180
msg = None
11791181
elif typ.arg_names[i] in {"self", "cls"}:
11801182
msg = message_registry.ERASED_SELF_TYPE_NOT_SUPERTYPE.format(
1181-
erased, ref_type
1183+
erased.str_with_options(self.options),
1184+
ref_type.str_with_options(self.options),
11821185
)
11831186
else:
11841187
msg = message_registry.MISSING_OR_INVALID_SELF_TYPE
@@ -1323,7 +1326,7 @@ def check_unbound_return_typevar(self, typ: CallableType) -> None:
13231326
):
13241327
self.note(
13251328
"Consider using the upper bound "
1326-
f"{format_type(typ.ret_type.upper_bound)} instead",
1329+
f"{format_type(typ.ret_type.upper_bound, self.options)} instead",
13271330
context=typ.ret_type,
13281331
)
13291332

@@ -1430,7 +1433,9 @@ def check___new___signature(self, fdef: FuncDef, typ: CallableType) -> None:
14301433
get_proper_type(bound_type.ret_type), (AnyType, Instance, TupleType, UninhabitedType)
14311434
):
14321435
self.fail(
1433-
message_registry.NON_INSTANCE_NEW_TYPE.format(format_type(bound_type.ret_type)),
1436+
message_registry.NON_INSTANCE_NEW_TYPE.format(
1437+
format_type(bound_type.ret_type, self.options)
1438+
),
14341439
fdef,
14351440
)
14361441
else:
@@ -1954,11 +1959,15 @@ def bind_and_map_method(
19541959
# If we have an overload, filter to overloads that match the self type.
19551960
# This avoids false positives for concrete subclasses of generic classes,
19561961
# see testSelfTypeOverrideCompatibility for an example.
1957-
filtered_items = [
1958-
item
1959-
for item in mapped_typ.items
1960-
if not item.arg_types or is_subtype(active_self_type, item.arg_types[0])
1961-
]
1962+
filtered_items = []
1963+
for item in mapped_typ.items:
1964+
if not item.arg_types:
1965+
filtered_items.append(item)
1966+
item_arg = item.arg_types[0]
1967+
if isinstance(item_arg, TypeVarType):
1968+
item_arg = item_arg.upper_bound
1969+
if is_subtype(active_self_type, item_arg):
1970+
filtered_items.append(item)
19621971
# If we don't have any filtered_items, maybe it's always a valid override
19631972
# of the superclass? However if you get to that point you're in murky type
19641973
# territory anyway, so we just preserve the type and have the behaviour match
@@ -2068,7 +2077,6 @@ def erase_override(t: Type) -> Type:
20682077
if not is_subtype(
20692078
original.arg_types[i], erase_override(override.arg_types[i])
20702079
):
2071-
20722080
arg_type_in_super = original.arg_types[i]
20732081

20742082
if isinstance(node, FuncDef):
@@ -2348,7 +2356,10 @@ class Baz(int, Foo, Bar, enum.Flag): ...
23482356
enum_base = base
23492357
continue
23502358
elif enum_base is not None and not base.type.is_enum:
2351-
self.fail(f'No non-enum mixin classes are allowed after "{enum_base}"', defn)
2359+
self.fail(
2360+
f'No non-enum mixin classes are allowed after "{enum_base.str_with_options(self.options)}"',
2361+
defn,
2362+
)
23522363
break
23532364

23542365
def check_enum_new(self, defn: ClassDef) -> None:
@@ -2373,7 +2384,7 @@ def has_new_method(info: TypeInfo) -> bool:
23732384
if candidate and has_new:
23742385
self.fail(
23752386
"Only a single data type mixin is allowed for Enum subtypes, "
2376-
'found extra "{}"'.format(base),
2387+
'found extra "{}"'.format(base.str_with_options(self.options)),
23772388
defn,
23782389
)
23792390
elif candidate:
@@ -2954,7 +2965,6 @@ def check_compatibility_all_supers(
29542965
and lvalue.kind in (MDEF, None)
29552966
and len(lvalue_node.info.bases) > 0 # None for Vars defined via self
29562967
):
2957-
29582968
for base in lvalue_node.info.mro[1:]:
29592969
tnode = base.names.get(lvalue_node.name)
29602970
if tnode is not None:
@@ -3976,7 +3986,12 @@ def check_member_assignment(
39763986

39773987
dunder_set = attribute_type.type.get_method("__set__")
39783988
if dunder_set is None:
3979-
self.fail(message_registry.DESCRIPTOR_SET_NOT_CALLABLE.format(attribute_type), context)
3989+
self.fail(
3990+
message_registry.DESCRIPTOR_SET_NOT_CALLABLE.format(
3991+
attribute_type.str_with_options(self.options)
3992+
),
3993+
context,
3994+
)
39803995
return AnyType(TypeOfAny.from_error), get_type, False
39813996

39823997
bound_method = analyze_decorator_or_funcbase_access(
@@ -4130,7 +4145,9 @@ def visit_expression_stmt(self, s: ExpressionStmt) -> None:
41304145
if error_note_and_code:
41314146
error_note, code = error_note_and_code
41324147
self.fail(
4133-
message_registry.TYPE_MUST_BE_USED.format(format_type(expr_type)), s, code=code
4148+
message_registry.TYPE_MUST_BE_USED.format(format_type(expr_type, self.options)),
4149+
s,
4150+
code=code,
41344151
)
41354152
self.note(error_note, s, code=code)
41364153

@@ -4960,7 +4977,9 @@ def _make_fake_typeinfo_and_full_name(
49604977
# We use the pretty_names_list for error messages but can't
49614978
# use it for the real name that goes into the symbol table
49624979
# because it can have dots in it.
4963-
pretty_names_list = pretty_seq(format_type_distinctly(*base_classes, bare=True), "and")
4980+
pretty_names_list = pretty_seq(
4981+
format_type_distinctly(*base_classes, options=self.options, bare=True), "and"
4982+
)
49644983
try:
49654984
info, full_name = _make_fake_typeinfo_and_full_name(base_classes, curr_module)
49664985
with self.msg.filter_errors() as local_errors:
@@ -4997,7 +5016,7 @@ def intersect_instance_callable(self, typ: Instance, callable_type: CallableType
49975016
gen_name = gen_unique_name(f"<callable subtype of {typ.type.name}>", cur_module.names)
49985017

49995018
# Synthesize a fake TypeInfo
5000-
short_name = format_type_bare(typ)
5019+
short_name = format_type_bare(typ, self.options)
50015020
cdef, info = self.make_fake_typeinfo(cur_module.fullname, gen_name, short_name, [typ])
50025021

50035022
# Build up a fake FuncDef so we can populate the symbol table.
@@ -5203,7 +5222,7 @@ def _check_for_truthy_type(self, t: Type, expr: Expression) -> None:
52035222
return
52045223

52055224
def format_expr_type() -> str:
5206-
typ = format_type(t)
5225+
typ = format_type(t, self.options)
52075226
if isinstance(expr, MemberExpr):
52085227
return f'Member "{expr.name}" has type {typ}'
52095228
elif isinstance(expr, RefExpr) and expr.fullname:
@@ -5218,14 +5237,16 @@ def format_expr_type() -> str:
52185237
return f"Expression has type {typ}"
52195238

52205239
if isinstance(t, FunctionLike):
5221-
self.fail(message_registry.FUNCTION_ALWAYS_TRUE.format(format_type(t)), expr)
5240+
self.fail(
5241+
message_registry.FUNCTION_ALWAYS_TRUE.format(format_type(t, self.options)), expr
5242+
)
52225243
elif isinstance(t, UnionType):
52235244
self.fail(message_registry.TYPE_ALWAYS_TRUE_UNIONTYPE.format(format_expr_type()), expr)
52245245
elif isinstance(t, Instance) and t.type.fullname == "typing.Iterable":
52255246
_, info = self.make_fake_typeinfo("typing", "Collection", "Collection", [])
52265247
self.fail(
52275248
message_registry.ITERABLE_ALWAYS_TRUE.format(
5228-
format_expr_type(), format_type(Instance(info, t.args))
5249+
format_expr_type(), format_type(Instance(info, t.args), self.options)
52295250
),
52305251
expr,
52315252
)
@@ -6010,7 +6031,9 @@ def check_subtype(
60106031
note_msg = ""
60116032
notes = notes or []
60126033
if subtype_label is not None or supertype_label is not None:
6013-
subtype_str, supertype_str = format_type_distinctly(orig_subtype, orig_supertype)
6034+
subtype_str, supertype_str = format_type_distinctly(
6035+
orig_subtype, orig_supertype, options=self.options
6036+
)
60146037
if subtype_label is not None:
60156038
extra_info.append(subtype_label + " " + subtype_str)
60166039
if supertype_label is not None:

mypy/checkexpr.py

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@
170170
# Type of callback user for checking individual function arguments. See
171171
# check_args() below for details.
172172
ArgChecker: _TypeAlias = Callable[
173-
[Type, Type, ArgKind, Type, int, int, CallableType, Optional[Type], Context, Context], None,
173+
[Type, Type, ArgKind, Type, int, int, CallableType, Optional[Type], Context, Context], None
174174
]
175175

176176
# Maximum nesting level for math union in overloads, setting this to large values
@@ -845,7 +845,7 @@ def check_typeddict_call_with_kwargs(
845845
# this may give a better error message.
846846
ret_type = callee
847847

848-
for (item_name, item_expected_type) in ret_type.items.items():
848+
for item_name, item_expected_type in ret_type.items.items():
849849
if item_name in kwargs:
850850
item_value = kwargs[item_name]
851851
self.chk.check_simple_assignment(
@@ -2126,7 +2126,9 @@ def check_argument_types(
21262126
if actual_kind == nodes.ARG_STAR2 and not self.is_valid_keyword_var_arg(
21272127
actual_type
21282128
):
2129-
is_mapping = is_subtype(actual_type, self.chk.named_type("typing.Mapping"))
2129+
is_mapping = is_subtype(
2130+
actual_type, self.chk.named_type("_typeshed.SupportsKeysAndGetItem")
2131+
)
21302132
self.msg.invalid_keyword_var_arg(actual_type, is_mapping, context)
21312133
expanded_actual = mapper.expand_actual_type(
21322134
actual_type, actual_kind, callee.arg_names[i], callee_arg_kind
@@ -3965,7 +3967,12 @@ def visit_type_application(self, tapp: TypeApplication) -> Type:
39653967
if isinstance(tapp.expr, RefExpr) and isinstance(tapp.expr.node, TypeAlias):
39663968
# Subscription of a (generic) alias in runtime context, expand the alias.
39673969
item = expand_type_alias(
3968-
tapp.expr.node, tapp.types, self.chk.fail, tapp.expr.node.no_args, tapp
3970+
tapp.expr.node,
3971+
tapp.types,
3972+
self.chk.fail,
3973+
tapp.expr.node.no_args,
3974+
tapp,
3975+
self.chk.options,
39693976
)
39703977
item = get_proper_type(item)
39713978
if isinstance(item, Instance):
@@ -4030,7 +4037,12 @@ class LongName(Generic[T]): ...
40304037
disallow_any = self.chk.options.disallow_any_generics and self.is_callee
40314038
item = get_proper_type(
40324039
set_any_tvars(
4033-
alias, ctx.line, ctx.column, disallow_any=disallow_any, fail=self.msg.fail
4040+
alias,
4041+
ctx.line,
4042+
ctx.column,
4043+
self.chk.options,
4044+
disallow_any=disallow_any,
4045+
fail=self.msg.fail,
40344046
)
40354047
)
40364048
if isinstance(item, Instance):
@@ -4346,7 +4358,11 @@ def visit_dict_expr(self, e: DictExpr) -> Type:
43464358
for arg in stargs:
43474359
if rv is None:
43484360
constructor = CallableType(
4349-
[self.chk.named_generic_type("typing.Mapping", [kt, vt])],
4361+
[
4362+
self.chk.named_generic_type(
4363+
"_typeshed.SupportsKeysAndGetItem", [kt, vt]
4364+
)
4365+
],
43504366
[nodes.ARG_POS],
43514367
[None],
43524368
self.chk.named_generic_type("builtins.dict", [kt, vt]),
@@ -4936,14 +4952,14 @@ def is_valid_keyword_var_arg(self, typ: Type) -> bool:
49364952
is_subtype(
49374953
typ,
49384954
self.chk.named_generic_type(
4939-
"typing.Mapping",
4955+
"_typeshed.SupportsKeysAndGetItem",
49404956
[self.named_type("builtins.str"), AnyType(TypeOfAny.special_form)],
49414957
),
49424958
)
49434959
or is_subtype(
49444960
typ,
49454961
self.chk.named_generic_type(
4946-
"typing.Mapping", [UninhabitedType(), UninhabitedType()]
4962+
"_typeshed.SupportsKeysAndGetItem", [UninhabitedType(), UninhabitedType()]
49474963
),
49484964
)
49494965
or isinstance(typ, ParamSpecType)

mypy/checkmember.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -637,7 +637,10 @@ def analyze_descriptor_access(descriptor_type: Type, mx: MemberContext) -> Type:
637637
dunder_get = descriptor_type.type.get_method("__get__")
638638
if dunder_get is None:
639639
mx.msg.fail(
640-
message_registry.DESCRIPTOR_GET_NOT_CALLABLE.format(descriptor_type), mx.context
640+
message_registry.DESCRIPTOR_GET_NOT_CALLABLE.format(
641+
descriptor_type.str_with_options(mx.msg.options)
642+
),
643+
mx.context,
641644
)
642645
return AnyType(TypeOfAny.from_error)
643646

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

695698
if not isinstance(inferred_dunder_get_type, CallableType):
696699
mx.msg.fail(
697-
message_registry.DESCRIPTOR_GET_NOT_CALLABLE.format(descriptor_type), mx.context
700+
message_registry.DESCRIPTOR_GET_NOT_CALLABLE.format(
701+
descriptor_type.str_with_options(mx.msg.options)
702+
),
703+
mx.context,
698704
)
699705
return AnyType(TypeOfAny.from_error)
700706

0 commit comments

Comments
 (0)