Skip to content

Commit 746fe01

Browse files
gvanrossumddfisher
authored andcommitted
Fix most errors reported by --disallow-untyped-defs/calls. (#1814)
I didn't get to everything: - A whole bunch of untyped calls are left in strconv.py; this code uses a few nasty data types (a list of strings and variously-sized tuples) and a ton of node types from nodes, and I got tired of typing. - A few untyped stdlib calls are left because the stubs for traceback and argparse are basically untyped. - A few nested functions where I couldn't figure out the argument types; here I used some Any types so no errors are reported.
1 parent f271497 commit 746fe01

19 files changed

+81
-74
lines changed

mypy/build.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -507,7 +507,7 @@ def remove_cwd_prefix_from_path(p: str) -> str:
507507
find_module_listdir_cache = {} # type: Dict[str, Optional[List[str]]]
508508

509509

510-
def find_module_clear_caches():
510+
def find_module_clear_caches() -> None:
511511
find_module_cache.clear()
512512
find_module_dir_cache.clear()
513513
find_module_listdir_cache.clear()
@@ -546,12 +546,11 @@ def is_file(path: str) -> bool:
546546
return os.path.isfile(path)
547547

548548

549-
def find_module(id: str, lib_path: Iterable[str]) -> str:
549+
def find_module(id: str, lib_path_arg: Iterable[str]) -> str:
550550
"""Return the path of the module source file, or None if not found."""
551-
if not isinstance(lib_path, tuple):
552-
lib_path = tuple(lib_path)
551+
lib_path = tuple(lib_path_arg)
553552

554-
def find():
553+
def find() -> Optional[str]:
555554
# If we're looking for a module like 'foo.bar.baz', it's likely that most of the
556555
# many elements of lib_path don't even have a subdirectory 'foo/bar'. Discover
557556
# that only once and cache it for when we look for modules like 'foo.bar.blah'
@@ -767,7 +766,7 @@ def select_options_affecting_cache(options: Options) -> Mapping[str, bool]:
767766
]
768767

769768

770-
def random_string():
769+
def random_string() -> str:
771770
return binascii.hexlify(os.urandom(8)).decode('ascii')
772771

773772

mypy/checker.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ def visit_file(self, file_node: MypyFile, path: str) -> None:
167167
self.fail(messages.ALL_MUST_BE_SEQ_STR.format(str_seq_s, all_s),
168168
all_.node)
169169

170-
def check_second_pass(self):
170+
def check_second_pass(self) -> None:
171171
"""Run second pass of type checking which goes through deferred nodes."""
172172
self.pass_num = 1
173173
for node, type_name in self.deferred_nodes:

mypy/checkexpr.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1192,7 +1192,7 @@ def visit_index_expr_helper(self, e: IndexExpr) -> Type:
11921192
e.method_type = method_type
11931193
return result
11941194

1195-
def visit_tuple_slice_helper(self, left_type: TupleType, slic: SliceExpr):
1195+
def visit_tuple_slice_helper(self, left_type: TupleType, slic: SliceExpr) -> Type:
11961196
begin = None # type: int
11971197
end = None # type: int
11981198
stride = None # type:int
@@ -1469,7 +1469,7 @@ def check_generator_or_comprehension(self, gen: GeneratorExpr,
14691469
return self.check_call(constructor,
14701470
[gen.left_expr], [nodes.ARG_POS], gen)[0]
14711471

1472-
def visit_dictionary_comprehension(self, e: DictionaryComprehension):
1472+
def visit_dictionary_comprehension(self, e: DictionaryComprehension) -> Type:
14731473
"""Type check a dictionary comprehension."""
14741474
self.check_for_comp(e)
14751475

mypy/checkstrformat.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ def __init__(self, key: str, flags: str, width: str, precision: str, type: str)
2525
self.precision = precision
2626
self.type = type
2727

28-
def has_key(self):
28+
def has_key(self) -> bool:
2929
return self.key is not None
3030

31-
def has_star(self):
31+
def has_star(self) -> bool:
3232
return self.width == '*' or self.precision == '*'
3333

3434

mypy/docstring.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,23 +83,23 @@
8383

8484

8585
class DocstringTypes(object):
86-
def __init__(self):
86+
def __init__(self) -> None:
8787
self.args = OrderedDict() # type: Dict[str, Optional[str]]
8888
self.rettype = None # type: Optional[str]
8989

9090
def as_type_str(self) -> str:
9191
return ('(' + ','.join([v or 'Any' for v in self.args.values()]) +
9292
') -> ' + (self.rettype or 'Any'))
9393

94-
def __str__(self):
94+
def __str__(self) -> str:
9595
return repr({'args': self.args, 'return': self.rettype})
9696

9797

9898
def wsprefix(s: str) -> str:
9999
return s[:len(s) - len(s.lstrip())]
100100

101101

102-
def scrubtype(typestr: Optional[str], only_known=False) -> Optional[str]:
102+
def scrubtype(typestr: Optional[str], only_known: bool =False) -> Optional[str]:
103103
if typestr is None:
104104
return typestr
105105

mypy/fastparse.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,9 @@
3636
' Python 3.3 and greater.')
3737
sys.exit(1)
3838

39-
T = TypeVar('T')
40-
U = TypeVar('U')
39+
T = TypeVar('T', bound=Union[ast35.expr, ast35.stmt])
40+
U = TypeVar('U', bound=Node)
41+
V = TypeVar('V')
4142

4243
TYPE_COMMENT_SYNTAX_ERROR = 'syntax error in type comment'
4344
TYPE_COMMENT_AST_ERROR = 'invalid type comment'
@@ -92,16 +93,16 @@ def parse_type_comment(type_comment: str, line: int) -> Type:
9293
return TypeConverter(line=line).visit(typ.body)
9394

9495

95-
def with_line(f: Callable[[Any, T], U]) -> Callable[[Any, T], U]:
96+
def with_line(f: Callable[['ASTConverter', T], U]) -> Callable[['ASTConverter', T], U]:
9697
@wraps(f)
97-
def wrapper(self, ast):
98+
def wrapper(self: 'ASTConverter', ast: T) -> U:
9899
node = f(self, ast)
99100
node.set_line(ast.lineno)
100101
return node
101102
return wrapper
102103

103104

104-
def find(f: Callable[[T], bool], seq: Sequence[T]) -> T:
105+
def find(f: Callable[[V], bool], seq: Sequence[V]) -> V:
105106
for item in seq:
106107
if f(item):
107108
return item
@@ -308,7 +309,7 @@ def set_type_optional(self, type: Type, initializer: Node) -> None:
308309
type.optional = optional
309310

310311
def transform_args(self, args: ast35.arguments, line: int) -> List[Argument]:
311-
def make_argument(arg, default, kind):
312+
def make_argument(arg: ast35.arg, default: Optional[ast35.expr], kind: int) -> Argument:
312313
arg_type = TypeConverter(line=line).visit(arg.annotation)
313314
converted_default = self.visit(default)
314315
self.set_type_optional(arg_type, converted_default)
@@ -531,7 +532,7 @@ def visit_BoolOp(self, n: ast35.BoolOp) -> Node:
531532
raise RuntimeError('unknown BoolOp ' + str(type(n)))
532533

533534
# potentially inefficient!
534-
def group(vals):
535+
def group(vals: List[Node]) -> Node:
535536
if len(vals) == 2:
536537
return OpExpr(op, vals[0], vals[1])
537538
else:
@@ -649,7 +650,7 @@ def visit_Compare(self, n: ast35.Compare) -> Node:
649650
# keyword = (identifier? arg, expr value)
650651
@with_line
651652
def visit_Call(self, n: ast35.Call) -> Node:
652-
def is_star2arg(k):
653+
def is_star2arg(k: ast35.keyword) -> bool:
653654
return k.arg is None
654655

655656
arg_types = self.visit_list(

mypy/git.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,23 +70,23 @@ def warn_no_git_executable() -> None:
7070
"git executable not in path.", file=sys.stderr)
7171

7272

73-
def warn_dirty(dir) -> None:
73+
def warn_dirty(dir: str) -> None:
7474
print("Warning: git module '{}' has uncommitted changes.".format(dir),
7575
file=sys.stderr)
7676
print("Go to the directory", file=sys.stderr)
7777
print(" {}".format(dir), file=sys.stderr)
7878
print("and commit or reset your changes", file=sys.stderr)
7979

8080

81-
def warn_extra_files(dir) -> None:
81+
def warn_extra_files(dir: str) -> None:
8282
print("Warning: git module '{}' has untracked files.".format(dir),
8383
file=sys.stderr)
8484
print("Go to the directory", file=sys.stderr)
8585
print(" {}".format(dir), file=sys.stderr)
8686
print("and add & commit your new files.", file=sys.stderr)
8787

8888

89-
def chdir_prefix(dir) -> str:
89+
def chdir_prefix(dir: str) -> str:
9090
"""Return the command to change to the target directory, plus '&&'."""
9191
if os.path.relpath(dir) != ".":
9292
return "cd " + pipes.quote(dir) + " && "

mypy/lex.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ def __init__(self, string: str, type: int, message: str = None) -> None:
142142
self.type = type
143143
self.message = message
144144

145-
def __str__(self):
145+
def __str__(self) -> str:
146146
if self.message:
147147
return 'LexError(%s)' % self.message
148148
else:

mypy/main.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import re
66
import sys
77

8-
from typing import Optional, Dict, List, Set, Tuple
8+
from typing import Any, Dict, List, Optional, Set, Tuple
99

1010
from mypy import build
1111
from mypy import defaults
@@ -86,21 +86,21 @@ def type_check_only(sources: List[BuildSource],
8686

8787

8888
class SplitNamespace:
89-
def __init__(self, standard_namespace, alt_namespace, alt_prefix):
89+
def __init__(self, standard_namespace: object, alt_namespace: object, alt_prefix: str) -> None:
9090
self.__dict__['_standard_namespace'] = standard_namespace
9191
self.__dict__['_alt_namespace'] = alt_namespace
9292
self.__dict__['_alt_prefix'] = alt_prefix
9393

94-
def _get(self):
94+
def _get(self) -> Tuple[Any, Any]:
9595
return (self._standard_namespace, self._alt_namespace)
9696

97-
def __setattr__(self, name, value):
97+
def __setattr__(self, name: str, value: Any) -> None:
9898
if name.startswith(self._alt_prefix):
9999
setattr(self._alt_namespace, name[len(self._alt_prefix):], value)
100100
else:
101101
setattr(self._standard_namespace, name, value)
102102

103-
def __getattr__(self, name):
103+
def __getattr__(self, name: str) -> Any:
104104
if name.startswith(self._alt_prefix):
105105
return getattr(self._alt_namespace, name[len(self._alt_prefix):])
106106
else:
@@ -121,7 +121,7 @@ def process_options(args: List[str]) -> Tuple[List[BuildSource], Options]:
121121
parser = argparse.ArgumentParser(prog='mypy', epilog=FOOTER,
122122
formatter_class=help_factory)
123123

124-
def parse_version(v):
124+
def parse_version(v: str) -> Tuple[int, int]:
125125
m = re.match(r'\A(\d)\.(\d+)\Z', v)
126126
if m:
127127
return int(m.group(1)), int(m.group(2))

mypy/meet.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -270,10 +270,10 @@ def visit_type_type(self, t: TypeType) -> Type:
270270
else:
271271
return self.default(self.s)
272272

273-
def meet(self, s, t):
273+
def meet(self, s: Type, t: Type) -> Type:
274274
return meet_types(s, t)
275275

276-
def default(self, typ):
276+
def default(self, typ: Type) -> Type:
277277
if isinstance(typ, UnboundType):
278278
return AnyType()
279279
elif isinstance(typ, Void) or isinstance(typ, ErrorType):

mypy/nodes.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,12 @@ def deserialize(cls, data: JsonDict) -> 'OverloadedFuncDef':
343343
class Argument(Node):
344344
"""A single argument in a FuncItem."""
345345

346+
variable = None # type: Var
347+
type_annotation = None # type: Optional[mypy.types.Type]
348+
initializater = None # type: Optional[Expression]
349+
kind = None # type: int
350+
initialization_statement = None # type: Optional[AssignmentStmt]
351+
346352
def __init__(self, variable: 'Var', type_annotation: 'Optional[mypy.types.Type]',
347353
initializer: Optional[Expression], kind: int,
348354
initialization_statement: Optional['AssignmentStmt'] = None) -> None:
@@ -438,7 +444,7 @@ def set_line(self, target: Union[Token, Node, int]) -> Node:
438444
arg.set_line(self.line)
439445
return self
440446

441-
def is_dynamic(self):
447+
def is_dynamic(self) -> bool:
442448
return self.type is None
443449

444450

mypy/options.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from mypy import defaults
22
import pprint
3+
from typing import Any
34

45

56
class BuildType:
@@ -55,11 +56,11 @@ def __init__(self) -> None:
5556
self.fast_parser = False
5657
self.incremental = False
5758

58-
def __eq__(self, other):
59+
def __eq__(self, other: object) -> bool:
5960
return self.__class__ == other.__class__ and self.__dict__ == other.__dict__
6061

61-
def __ne__(self, other):
62+
def __ne__(self, other: object) -> bool:
6263
return not self == other
6364

64-
def __repr__(self):
65+
def __repr__(self) -> str:
6566
return 'Options({})'.format(pprint.pformat(self.__dict__))

mypy/parse.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1528,7 +1528,7 @@ def parse_set_expr(self, first: Node) -> SetExpr:
15281528
expr = SetExpr(items)
15291529
return expr
15301530

1531-
def parse_set_comprehension(self, expr: Node):
1531+
def parse_set_comprehension(self, expr: Node) -> SetComprehension:
15321532
gen = self.parse_generator_expr(expr)
15331533
self.expect('}')
15341534
set_comp = SetComprehension(gen)
@@ -2000,7 +2000,7 @@ def token_repr(tok: Token) -> str:
20002000
# Parse a file and dump the AST (or display errors).
20012001
import sys
20022002

2003-
def usage():
2003+
def usage() -> None:
20042004
print('Usage: parse.py [--py2] [--quiet] FILE [...]', file=sys.stderr)
20052005
sys.exit(2)
20062006

mypy/report.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ def __init__(self) -> None:
6464
super().__init__()
6565
self.counts = [0, 0]
6666

67-
def visit_func_def(self, defn: FuncDef):
67+
def visit_func_def(self, defn: FuncDef) -> None:
6868
self.counts[defn.type is not None] += 1
6969

7070

mypy/semanal.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -605,7 +605,7 @@ def unbind_class_type_vars(self) -> None:
605605
def analyze_class_decorator(self, defn: ClassDef, decorator: Node) -> None:
606606
decorator.accept(self)
607607

608-
def setup_is_builtinclass(self, defn: ClassDef):
608+
def setup_is_builtinclass(self, defn: ClassDef) -> None:
609609
for decorator in defn.decorators:
610610
if refers_to_fullname(decorator, 'typing.builtinclass'):
611611
defn.is_builtinclass = True

mypy/solve.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313

1414
def solve_constraints(vars: List[TypeVarId], constraints: List[Constraint],
15-
strict=True) -> List[Type]:
15+
strict: bool =True) -> List[Type]:
1616
"""Solve type constraints.
1717
1818
Return the best type(s) for type variables; each type can be None if the value of the variable

mypy/strconv.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import re
44
import os
55

6-
import typing
6+
from typing import Any, List
77

88
from mypy.util import dump_tagged, short_type
99
import mypy.nodes
@@ -21,7 +21,7 @@ class StrConv(NodeVisitor[str]):
2121
ExpressionStmt:1(
2222
IntExpr(1)))
2323
"""
24-
def dump(self, nodes, obj):
24+
def dump(self, nodes: List[Any], obj: 'mypy.nodes.Node') -> str:
2525
"""Convert a list of items to a multiline pretty-printed string.
2626
2727
The tag is produced from the type name of obj and its line
@@ -30,7 +30,7 @@ def dump(self, nodes, obj):
3030
"""
3131
return dump_tagged(nodes, short_type(obj) + ':' + str(obj.line))
3232

33-
def func_helper(self, o):
33+
def func_helper(self, o: 'mypy.nodes.FuncItem') -> List[Any]:
3434
"""Return a list in a format suitable for dump() that represents the
3535
arguments and the body of a function. The caller can then decorate the
3636
array with information specific to methods, global functions or
@@ -50,7 +50,7 @@ def func_helper(self, o):
5050
extra.append(('VarArg', [o.arguments[i].variable]))
5151
elif kind == mypy.nodes.ARG_STAR2:
5252
extra.append(('DictVarArg', [o.arguments[i].variable]))
53-
a = []
53+
a = [] # type: List[Any]
5454
if args:
5555
a.append(('Args', args))
5656
if o.type:
@@ -65,9 +65,9 @@ def func_helper(self, o):
6565

6666
# Top-level structures
6767

68-
def visit_mypy_file(self, o):
68+
def visit_mypy_file(self, o: 'mypy.nodes.MypyFile') -> str:
6969
# Skip implicit definitions.
70-
a = [o.defs]
70+
a = [o.defs] # type: List[Any]
7171
if o.is_bom:
7272
a.insert(0, 'BOM')
7373
# Omit path to special file with name "main". This is used to simplify
@@ -82,7 +82,7 @@ def visit_mypy_file(self, o):
8282
for line in sorted(o.ignored_lines)))
8383
return self.dump(a, o)
8484

85-
def visit_import(self, o):
85+
def visit_import(self, o: 'mypy.nodes.Import') -> str:
8686
a = []
8787
for id, as_id in o.ids:
8888
if as_id is not None:

0 commit comments

Comments
 (0)