Skip to content

Commit f45652d

Browse files
committed
Enable warn_unreachable for mypy self-check
1 parent 4a76a1a commit f45652d

23 files changed

+70
-153
lines changed

mypy/build.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1069,7 +1069,7 @@ def read_plugins_snapshot(manager: BuildManager) -> dict[str, str] | None:
10691069
if snapshot is None:
10701070
return None
10711071
if not isinstance(snapshot, dict):
1072-
manager.log(f"Could not load plugins snapshot: cache is not a dict: {type(snapshot)}")
1072+
manager.log(f"Could not load plugins snapshot: cache is not a dict: {type(snapshot)}") # type: ignore[unreachable]
10731073
return None
10741074
return snapshot
10751075

@@ -1285,7 +1285,7 @@ def find_cache_meta(id: str, path: str, manager: BuildManager) -> CacheMeta | No
12851285
if meta is None:
12861286
return None
12871287
if not isinstance(meta, dict):
1288-
manager.log(f"Could not load cache for {id}: meta cache is not a dict: {repr(meta)}")
1288+
manager.log(f"Could not load cache for {id}: meta cache is not a dict: {repr(meta)}") # type: ignore[unreachable]
12891289
return None
12901290
m = cache_meta_from_dict(meta, data_json)
12911291
t2 = time.time()

mypy/checker.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
from mypy.mro import MroError, calculate_mro
4444
from mypy.nodes import (
4545
ARG_NAMED,
46+
SYMBOL_FUNCBASE_TYPES,
4647
ARG_POS,
4748
ARG_STAR,
4849
CONTRAVARIANT,
@@ -2780,7 +2781,7 @@ def check_multiple_inheritance(self, typ: TypeInfo) -> None:
27802781
def determine_type_of_member(self, sym: SymbolTableNode) -> Type | None:
27812782
if sym.type is not None:
27822783
return sym.type
2783-
if isinstance(sym.node, FuncBase):
2784+
if isinstance(sym.node, SYMBOL_FUNCBASE_TYPES):
27842785
return self.function_type(sym.node)
27852786
if isinstance(sym.node, TypeInfo):
27862787
if sym.node.typeddict_type:
@@ -4340,7 +4341,7 @@ def simple_rvalue(self, rvalue: Expression) -> bool:
43404341
if isinstance(rvalue, (IntExpr, StrExpr, BytesExpr, FloatExpr, RefExpr)):
43414342
return True
43424343
if isinstance(rvalue, CallExpr):
4343-
if isinstance(rvalue.callee, RefExpr) and isinstance(rvalue.callee.node, FuncBase):
4344+
if isinstance(rvalue.callee, RefExpr) and isinstance(rvalue.callee.node, SYMBOL_FUNCBASE_TYPES):
43444345
typ = rvalue.callee.node.type
43454346
if isinstance(typ, CallableType):
43464347
return not typ.variables

mypy/checkexpr.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2581,8 +2581,6 @@ def check_argument_types(
25812581
for actual, actual_type, actual_kind, callee_arg_type, callee_arg_kind in zip(
25822582
actuals, actual_types, actual_kinds, callee_arg_types, callee_arg_kinds
25832583
):
2584-
if actual_type is None:
2585-
continue # Some kind of error was already reported.
25862584
# Check that a *arg is valid as varargs.
25872585
expanded_actual = mapper.expand_actual_type(
25882586
actual_type,

mypy/checkmember.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1111,10 +1111,10 @@ def analyze_class_attribute_access(
11111111
t = erase_typevars(expand_type_by_instance(t, isuper), {tv.id for tv in def_vars})
11121112

11131113
is_classmethod = (is_decorated and cast(Decorator, node.node).func.is_class) or (
1114-
isinstance(node.node, FuncBase) and node.node.is_class
1114+
isinstance(node.node, SYMBOL_FUNCBASE_TYPES) and node.node.is_class
11151115
)
11161116
is_staticmethod = (is_decorated and cast(Decorator, node.node).func.is_static) or (
1117-
isinstance(node.node, FuncBase) and node.node.is_static
1117+
isinstance(node.node, SYMBOL_FUNCBASE_TYPES) and node.node.is_static
11181118
)
11191119
t = get_proper_type(t)
11201120
if isinstance(t, FunctionLike) and is_classmethod:
@@ -1156,7 +1156,7 @@ def analyze_class_attribute_access(
11561156
mx.not_ready_callback(name, mx.context)
11571157
return AnyType(TypeOfAny.from_error)
11581158
else:
1159-
assert isinstance(node.node, FuncBase)
1159+
assert isinstance(node.node, SYMBOL_FUNCBASE_TYPES)
11601160
typ = function_type(node.node, mx.named_type("builtins.function"))
11611161
# Note: if we are accessing class method on class object, the cls argument is bound.
11621162
# Annotated and/or explicit class methods go through other code paths above, for
@@ -1415,7 +1415,7 @@ def is_valid_constructor(n: SymbolNode | None) -> bool:
14151415
This includes normal functions, overloaded functions, and decorators
14161416
that return a callable type.
14171417
"""
1418-
if isinstance(n, FuncBase):
1418+
if isinstance(n, SYMBOL_FUNCBASE_TYPES):
14191419
return True
14201420
if isinstance(n, Decorator):
14211421
return isinstance(get_proper_type(n.type), FunctionLike)

mypy/constraints.py

Lines changed: 10 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -126,15 +126,6 @@ def infer_constraints_for_callable(
126126
param_spec_arg_names = []
127127
param_spec_arg_kinds = []
128128

129-
incomplete_star_mapping = False
130-
for i, actuals in enumerate(formal_to_actual):
131-
for actual in actuals:
132-
if actual is None and callee.arg_kinds[i] in (ARG_STAR, ARG_STAR2):
133-
# We can't use arguments to infer ParamSpec constraint, if only some
134-
# are present in the current inference pass.
135-
incomplete_star_mapping = True
136-
break
137-
138129
for i, actuals in enumerate(formal_to_actual):
139130
if isinstance(callee.arg_types[i], UnpackType):
140131
unpack_type = callee.arg_types[i]
@@ -230,17 +221,16 @@ def infer_constraints_for_callable(
230221
# constraints, instead store them and infer single constraint at the end.
231222
# It is impossible to map actual kind to formal kind, so use some heuristic.
232223
# This inference is used as a fallback, so relying on heuristic should be OK.
233-
if not incomplete_star_mapping:
234-
param_spec_arg_types.append(
235-
mapper.expand_actual_type(
236-
actual_arg_type, arg_kinds[actual], None, arg_kinds[actual]
237-
)
224+
param_spec_arg_types.append(
225+
mapper.expand_actual_type(
226+
actual_arg_type, arg_kinds[actual], None, arg_kinds[actual]
238227
)
239-
actual_kind = arg_kinds[actual]
240-
param_spec_arg_kinds.append(
241-
ARG_POS if actual_kind not in (ARG_STAR, ARG_STAR2) else actual_kind
242-
)
243-
param_spec_arg_names.append(arg_names[actual] if arg_names else None)
228+
)
229+
actual_kind = arg_kinds[actual]
230+
param_spec_arg_kinds.append(
231+
ARG_POS if actual_kind not in (ARG_STAR, ARG_STAR2) else actual_kind
232+
)
233+
param_spec_arg_names.append(arg_names[actual] if arg_names else None)
244234
else:
245235
actual_type = mapper.expand_actual_type(
246236
actual_arg_type,
@@ -253,7 +243,6 @@ def infer_constraints_for_callable(
253243
if (
254244
param_spec
255245
and not any(c.type_var == param_spec.id for c in constraints)
256-
and not incomplete_star_mapping
257246
):
258247
# Use ParamSpec constraint from arguments only if there are no other constraints,
259248
# since as explained above it is quite ad-hoc.
@@ -545,11 +534,7 @@ def any_constraints(options: list[list[Constraint] | None], eager: bool) -> list
545534
for option in valid_options:
546535
if option in trivial_options:
547536
continue
548-
if option is not None:
549-
merged_option: list[Constraint] | None = [merge_with_any(c) for c in option]
550-
else:
551-
merged_option = None
552-
merged_options.append(merged_option)
537+
merged_options.append([merge_with_any(c) for c in option])
553538
return any_constraints(list(merged_options), eager)
554539

555540
# If normal logic didn't work, try excluding trivially unsatisfiable constraint (due to

mypy/errors.py

Lines changed: 12 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1066,34 +1066,19 @@ def render_messages(self, errors: list[ErrorInfo]) -> list[ErrorTuple]:
10661066
(file, -1, -1, -1, -1, "note", f'In class "{e.type}":', e.allow_dups, None)
10671067
)
10681068

1069-
if isinstance(e.message, ErrorMessage):
1070-
result.append(
1071-
(
1072-
file,
1073-
e.line,
1074-
e.column,
1075-
e.end_line,
1076-
e.end_column,
1077-
e.severity,
1078-
e.message.value,
1079-
e.allow_dups,
1080-
e.code,
1081-
)
1082-
)
1083-
else:
1084-
result.append(
1085-
(
1086-
file,
1087-
e.line,
1088-
e.column,
1089-
e.end_line,
1090-
e.end_column,
1091-
e.severity,
1092-
e.message,
1093-
e.allow_dups,
1094-
e.code,
1095-
)
1069+
result.append(
1070+
(
1071+
file,
1072+
e.line,
1073+
e.column,
1074+
e.end_line,
1075+
e.end_column,
1076+
e.severity,
1077+
e.message,
1078+
e.allow_dups,
1079+
e.code,
10961080
)
1081+
)
10971082

10981083
prev_import_context = e.import_ctx
10991084
prev_function_or_member = e.function_or_member

mypy/messages.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2132,12 +2132,8 @@ def report_protocol_problems(
21322132
is_module = False
21332133
skip = []
21342134
if isinstance(subtype, TupleType):
2135-
if not isinstance(subtype.partial_fallback, Instance):
2136-
return
21372135
subtype = subtype.partial_fallback
21382136
elif isinstance(subtype, TypedDictType):
2139-
if not isinstance(subtype.fallback, Instance):
2140-
return
21412137
subtype = subtype.fallback
21422138
elif isinstance(subtype, TypeType):
21432139
if not isinstance(subtype.item, Instance):

mypy/nodes.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -171,10 +171,7 @@ class Node(Context):
171171
__slots__ = ()
172172

173173
def __str__(self) -> str:
174-
ans = self.accept(mypy.strconv.StrConv(options=Options()))
175-
if ans is None:
176-
return repr(self)
177-
return ans
174+
return self.accept(mypy.strconv.StrConv(options=Options()))
178175

179176
def str_with_options(self, options: Options) -> str:
180177
ans = self.accept(mypy.strconv.StrConv(options=options))
@@ -870,7 +867,7 @@ def deserialize(cls, data: JsonDict) -> FuncDef:
870867

871868
# All types that are both SymbolNodes and FuncBases. See the FuncBase
872869
# docstring for the rationale.
873-
SYMBOL_FUNCBASE_TYPES = (OverloadedFuncDef, FuncDef)
870+
SYMBOL_FUNCBASE_TYPES: Final = (OverloadedFuncDef, FuncDef)
874871

875872

876873
class Decorator(SymbolNode, Statement):
@@ -2551,6 +2548,10 @@ def name(self) -> str:
25512548
def fullname(self) -> str:
25522549
return self._fullname
25532550

2551+
# All types that are both SymbolNodes and Expressions.
2552+
# Use when common children of them are needed.
2553+
SYMBOL_NODE_EXPRESSION_TYPES: Final = (TypeVarLikeExpr, )
2554+
25542555

25552556
class TypeVarExpr(TypeVarLikeExpr):
25562557
"""Type variable expression TypeVar(...).
@@ -3250,7 +3251,7 @@ def get_method(self, name: str) -> FuncBase | Decorator | None:
32503251
for cls in self.mro:
32513252
if name in cls.names:
32523253
node = cls.names[name].node
3253-
if isinstance(node, FuncBase):
3254+
if isinstance(node, SYMBOL_FUNCBASE_TYPES):
32543255
return node
32553256
elif isinstance(node, Decorator): # Two `if`s make `mypyc` happy
32563257
return node
@@ -4009,7 +4010,8 @@ def __str__(self) -> str:
40094010
):
40104011
a.append(" " + str(key) + " : " + str(value))
40114012
else:
4012-
a.append(" <invalid item>")
4013+
# Used in debugging:
4014+
a.append(" <invalid item>") # type: ignore[unreachable]
40134015
a = sorted(a)
40144016
a.insert(0, "SymbolTable(")
40154017
a[-1] += ")"

mypy/plugins/default.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -554,7 +554,7 @@ def tuple_mul_callback(ctx: MethodContext) -> Type:
554554
value = arg_type.last_known_value.value
555555
if isinstance(value, int):
556556
return ctx.type.copy_modified(items=ctx.type.items * value)
557-
elif isinstance(ctx.type, LiteralType):
557+
elif isinstance(arg_type, LiteralType):
558558
value = arg_type.value
559559
if isinstance(value, int):
560560
return ctx.type.copy_modified(items=ctx.type.items * value)

mypy/plugins/functools.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import mypy.plugin
99
import mypy.semanal
1010
from mypy.argmap import map_actuals_to_formals
11-
from mypy.nodes import ARG_POS, ARG_STAR2, ArgKind, Argument, CallExpr, FuncItem, NameExpr, Var
11+
from mypy.nodes import SYMBOL_FUNCBASE_TYPES, ARG_POS, ARG_STAR2, ArgKind, Argument, CallExpr, FuncItem, NameExpr, Var
1212
from mypy.plugins.common import add_method_to_class
1313
from mypy.typeops import get_all_type_vars
1414
from mypy.types import (
@@ -108,7 +108,7 @@ def _analyze_class(ctx: mypy.plugin.ClassDefContext) -> dict[str, _MethodInfo |
108108
for name in _ORDERING_METHODS:
109109
if name in cls.names and name not in comparison_methods:
110110
node = cls.names[name].node
111-
if isinstance(node, FuncItem) and isinstance(node.type, CallableType):
111+
if isinstance(node, SYMBOL_FUNCBASE_TYPES) and isinstance(node.type, CallableType):
112112
comparison_methods[name] = _MethodInfo(node.is_static, node.type)
113113
continue
114114

0 commit comments

Comments
 (0)