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

Use asserts instead of casts where possible #14860

Merged
merged 5 commits into from
Mar 11, 2023
Merged
Show file tree
Hide file tree
Changes from 3 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
5 changes: 3 additions & 2 deletions mypy/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@

import sys
from io import StringIO
from typing import Callable, TextIO, cast
from typing import Callable, TextIO


def _run(main_wrapper: Callable[[TextIO, TextIO], None]) -> tuple[str, str, int]:
Expand All @@ -59,7 +59,8 @@ def _run(main_wrapper: Callable[[TextIO, TextIO], None]) -> tuple[str, str, int]
main_wrapper(stdout, stderr)
exit_status = 0
except SystemExit as system_exit:
exit_status = cast(int, system_exit.code)
assert isinstance(system_exit.code, int)
exit_status = system_exit.code

return stdout.getvalue(), stderr.getvalue(), exit_status

Expand Down
27 changes: 16 additions & 11 deletions mypy/checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -629,7 +629,8 @@ def _visit_overloaded_func_def(self, defn: OverloadedFuncDef) -> None:

if defn.is_property:
# HACK: Infer the type of the property.
self.visit_decorator(cast(Decorator, defn.items[0]))
assert isinstance(defn.items[0], Decorator)
self.visit_decorator(defn.items[0])
for fdef in defn.items:
assert isinstance(fdef, Decorator)
self.check_func_item(fdef.func, name=fdef.func.name, allow_empty=True)
Expand Down Expand Up @@ -1753,7 +1754,8 @@ def expand_typevars(
result: list[tuple[FuncItem, CallableType]] = []
for substitutions in itertools.product(*subst):
mapping = dict(substitutions)
expanded = cast(CallableType, expand_type(typ, mapping))
expanded = expand_type(typ, mapping)
assert isinstance(expanded, CallableType)
result.append((expand_func(defn, mapping), expanded))
return result
else:
Expand Down Expand Up @@ -2576,9 +2578,8 @@ def check_import(self, node: ImportBase) -> None:
if lvalue_type is None:
# TODO: This is broken.
JelleZijlstra marked this conversation as resolved.
Show resolved Hide resolved
lvalue_type = AnyType(TypeOfAny.special_form)
message = message_registry.INCOMPATIBLE_IMPORT_OF.format(
cast(NameExpr, assign.rvalue).name
)
assert isinstance(assign.rvalue, NameExpr)
message = message_registry.INCOMPATIBLE_IMPORT_OF.format(assign.rvalue.name)
self.check_simple_assignment(
lvalue_type,
assign.rvalue,
Expand Down Expand Up @@ -3658,8 +3659,8 @@ def check_lvalue(self, lvalue: Lvalue) -> tuple[Type | None, IndexExpr | None, V
not isinstance(lvalue, NameExpr) or isinstance(lvalue.node, Var)
):
if isinstance(lvalue, NameExpr):
inferred = cast(Var, lvalue.node)
assert isinstance(inferred, Var)
assert isinstance(lvalue.node, Var)
inferred = lvalue.node
else:
assert isinstance(lvalue, MemberExpr)
self.expr_checker.accept(lvalue.expr)
Expand Down Expand Up @@ -4985,7 +4986,8 @@ def intersect_instance_callable(self, typ: Instance, callable_type: CallableType
# In order for this to work in incremental mode, the type we generate needs to
# have a valid fullname and a corresponding entry in a symbol table. We generate
# a unique name inside the symbol table of the current module.
cur_module = cast(MypyFile, self.scope.stack[0])
cur_module = self.scope.stack[0]
assert isinstance(cur_module, MypyFile)
gen_name = gen_unique_name(f"<callable subtype of {typ.type.name}>", cur_module.names)

# Synthesize a fake TypeInfo
Expand Down Expand Up @@ -6197,7 +6199,8 @@ def lookup(self, name: str) -> SymbolTableNode:
else:
b = self.globals.get("__builtins__", None)
if b:
table = cast(MypyFile, b.node).names
assert isinstance(b.node, MypyFile)
table = b.node.names
if name in table:
return table[name]
raise KeyError(f"Failed lookup: {name}")
Expand All @@ -6211,7 +6214,8 @@ def lookup_qualified(self, name: str) -> SymbolTableNode:
for i in range(1, len(parts) - 1):
sym = n.names.get(parts[i])
assert sym is not None, "Internal error: attempted lookup of unknown name"
n = cast(MypyFile, sym.node)
assert isinstance(sym.node, MypyFile)
n = sym.node
last = parts[-1]
if last in n.names:
return n.names[last]
Expand Down Expand Up @@ -6515,7 +6519,8 @@ def is_writable_attribute(self, node: Node) -> bool:
return False
return True
elif isinstance(node, OverloadedFuncDef) and node.is_property:
first_item = cast(Decorator, node.items[0])
first_item = node.items[0]
assert isinstance(first_item, Decorator)
return first_item.var.is_settable_property
return False

Expand Down
4 changes: 3 additions & 1 deletion mypy/checkexpr.py
Original file line number Diff line number Diff line change
Expand Up @@ -5518,7 +5518,9 @@ def merge_typevars_in_callables_by_name(
variables.append(tv)
rename[tv.id] = unique_typevars[name]

target = cast(CallableType, expand_type(target, rename))
t = expand_type(target, rename)
assert isinstance(t, CallableType)
target = t
output.append(target)

return output, variables
Expand Down
6 changes: 4 additions & 2 deletions mypy/checkmember.py
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,8 @@ def analyze_instance_member_access(

if method.is_property:
assert isinstance(method, OverloadedFuncDef)
first_item = cast(Decorator, method.items[0])
first_item = method.items[0]
assert isinstance(first_item, Decorator)
return analyze_var(name, first_item.var, typ, info, mx)
if mx.is_lvalue:
mx.msg.cant_assign_to_method(mx.context)
Expand Down Expand Up @@ -1150,7 +1151,8 @@ class B(A[str]): pass
t = freshen_all_functions_type_vars(t)
t = bind_self(t, original_type, is_classmethod=True)
assert isuper is not None
t = cast(CallableType, expand_type_by_instance(t, isuper))
t = expand_type_by_instance(t, isuper)
AlexWaygood marked this conversation as resolved.
Show resolved Hide resolved
assert isinstance(t, CallableType)
freeze_all_type_vars(t)
return t.copy_modified(variables=list(tvars) + list(t.variables))
elif isinstance(t, Overloaded):
Expand Down
5 changes: 3 additions & 2 deletions mypy/expandtype.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,9 @@ def freshen_function_type_vars(callee: F) -> F:
tv = ParamSpecType.new_unification_variable(v)
tvs.append(tv)
tvmap[v.id] = tv
fresh = cast(CallableType, expand_type(callee, tvmap)).copy_modified(variables=tvs)
return cast(F, fresh)
expanded = expand_type(callee, tvmap)
assert isinstance(expanded, CallableType)
return cast(F, expanded.copy_modified(variables=tvs))
else:
assert isinstance(callee, Overloaded)
fresh_overload = Overloaded([freshen_function_type_vars(item) for item in callee.items])
Expand Down
4 changes: 3 additions & 1 deletion mypy/fastparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -665,7 +665,9 @@ def fix_function_overloads(self, stmts: list[Statement]) -> list[Statement]:
if current_overload and current_overload_name == last_if_stmt_overload_name:
# Remove last stmt (IfStmt) from ret if the overload names matched
# Only happens if no executable block had been found in IfStmt
skipped_if_stmts.append(cast(IfStmt, ret.pop()))
popped = ret.pop()
assert isinstance(popped, IfStmt)
skipped_if_stmts.append(popped)
if current_overload and skipped_if_stmts:
# Add bare IfStmt (without overloads) to ret
# Required for mypy to be able to still check conditions
Expand Down
3 changes: 2 additions & 1 deletion mypy/nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -2179,7 +2179,8 @@ def name(self) -> str:

def expr(self) -> Expression:
"""Return the expression (the body) of the lambda."""
ret = cast(ReturnStmt, self.body.body[-1])
ret = self.body.body[-1]
assert isinstance(ret, ReturnStmt)
expr = ret.expr
assert expr is not None # lambda can't have empty body
return expr
Expand Down
5 changes: 3 additions & 2 deletions mypy/report.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import tokenize
from abc import ABCMeta, abstractmethod
from operator import attrgetter
from typing import Any, Callable, Dict, Iterator, Tuple, cast
from typing import Any, Callable, Dict, Iterator, Tuple
from typing_extensions import Final, TypeAlias as _TypeAlias
from urllib.request import pathname2url

Expand Down Expand Up @@ -704,8 +704,9 @@ def __init__(self, reports: Reports, output_dir: str) -> None:
super().__init__(reports, output_dir)

memory_reporter = reports.add_report("memory-xml", "<memory>")
assert isinstance(memory_reporter, MemoryXmlReporter)
# The dependency will be called first.
self.memory_xml = cast(MemoryXmlReporter, memory_reporter)
self.memory_xml = memory_reporter


class XmlReporter(AbstractXmlReporter):
Expand Down
6 changes: 4 additions & 2 deletions mypy/semanal.py
Original file line number Diff line number Diff line change
Expand Up @@ -1314,7 +1314,8 @@ def analyze_property_with_multi_part_definition(self, defn: OverloadedFuncDef) -
"""
defn.is_property = True
items = defn.items
first_item = cast(Decorator, defn.items[0])
first_item = defn.items[0]
assert isinstance(first_item, Decorator)
deleted_items = []
for i, item in enumerate(items[1:]):
if isinstance(item, Decorator):
Expand Down Expand Up @@ -1357,7 +1358,8 @@ def analyze_function_body(self, defn: FuncItem) -> None:
# Bind the type variables again to visit the body.
if defn.type:
a = self.type_analyzer()
typ = cast(CallableType, defn.type)
typ = defn.type
assert isinstance(typ, CallableType)
a.bind_function_type_variables(typ, defn)
for i in range(len(typ.arg_types)):
store_argument_type(defn, i, typ, self.named_type)
Expand Down
2 changes: 1 addition & 1 deletion mypy/semanal_namedtuple.py
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,7 @@ def parse_namedtuple_args(
if not isinstance(args[0], StrExpr):
self.fail(f'"{type_name}()" expects a string literal as the first argument', call)
return None
typename = cast(StrExpr, call.args[0]).value
typename = args[0].value
types: list[Type] = []
tvar_defs = []
if not isinstance(args[1], (ListExpr, TupleExpr)):
Expand Down
6 changes: 4 additions & 2 deletions mypy/server/astdiff.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class level -- these are handled at attribute level (say, 'mod.Cls.method'

from __future__ import annotations

from typing import Sequence, Tuple, Union, cast
from typing import Sequence, Tuple, Union
from typing_extensions import TypeAlias as _TypeAlias

from mypy.expandtype import expand_type
Expand Down Expand Up @@ -442,7 +442,9 @@ def normalize_callable_variables(self, typ: CallableType) -> CallableType:
tv = v.copy_modified(id=tid)
tvs.append(tv)
tvmap[v.id] = tv
return cast(CallableType, expand_type(typ, tvmap)).copy_modified(variables=tvs)
expanded = expand_type(typ, tvmap)
assert isinstance(expanded, CallableType)
return expanded.copy_modified(variables=tvs)

def visit_tuple_type(self, typ: TupleType) -> SnapshotItem:
return ("TupleType", snapshot_types(typ.items))
Expand Down
3 changes: 2 additions & 1 deletion mypy/server/astmerge.py
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,8 @@ def fixup_and_reset_typeinfo(self, node: TypeInfo) -> TypeInfo:
if node in self.replacements:
# The subclass relationships may change, so reset all caches relevant to the
# old MRO.
new = cast(TypeInfo, self.replacements[node])
new = self.replacements[node]
assert isinstance(new, TypeInfo)
type_state.reset_all_subtype_caches_for(new)
return self.fixup(node)

Expand Down
8 changes: 5 additions & 3 deletions mypy/stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import os
from collections import Counter
from contextlib import contextmanager
from typing import Iterator, cast
from typing import Iterator
from typing_extensions import Final

from mypy import nodes
Expand Down Expand Up @@ -154,10 +154,12 @@ def visit_func_def(self, o: FuncDef) -> None:
)
return
for defn in o.expanded:
self.visit_func_def(cast(FuncDef, defn))
assert isinstance(defn, FuncDef)
self.visit_func_def(defn)
else:
if o.type:
sig = cast(CallableType, o.type)
assert isinstance(o.type, CallableType)
sig = o.type
arg_types = sig.arg_types
if sig.arg_names and sig.arg_names[0] == "self" and not self.inferred:
arg_types = arg_types[1:]
Expand Down
5 changes: 3 additions & 2 deletions mypy/test/testfinegrained.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import re
import sys
import unittest
from typing import Any, cast
from typing import Any

import pytest

Expand Down Expand Up @@ -169,7 +169,8 @@ def get_options(self, source: str, testcase: DataDrivenTestCase, build_cache: bo

def run_check(self, server: Server, sources: list[BuildSource]) -> list[str]:
response = server.check(sources, export_types=True, is_tty=False, terminal_width=-1)
out = cast(str, response["out"] or response["err"])
out = response["out"] or response["err"]
assert isinstance(out, str)
return out.splitlines()

def build(self, options: Options, sources: list[BuildSource]) -> list[str]:
Expand Down
6 changes: 4 additions & 2 deletions mypyc/irbuild/expression.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

from __future__ import annotations

from typing import Callable, Sequence, cast
from typing import Callable, Sequence

from mypy.nodes import (
ARG_POS,
Expand Down Expand Up @@ -704,7 +704,9 @@ def transform_comparison_expr(builder: IRBuilder, e: ComparisonExpr) -> Value:
lhs = e.operands[0]
mypy_file = builder.graph["builtins"].tree
assert mypy_file is not None
bool_type = Instance(cast(TypeInfo, mypy_file.names["bool"].node), [])
info = mypy_file.names["bool"].node
assert isinstance(info, TypeInfo)
bool_type = Instance(info, [])
exprs = []
for item in items:
expr = ComparisonExpr([cmp_op], [lhs, item])
Expand Down