diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py
index fee0957fc0d0..f1b8ebcaf54c 100644
--- a/mypy/checkexpr.py
+++ b/mypy/checkexpr.py
@@ -861,7 +861,7 @@ def visit_op_expr(self, e: OpExpr) -> Type:
if e.op == '*' and isinstance(e.left, ListExpr):
# Expressions of form [...] * e get special type inference.
return self.check_list_multiply(e)
- if e.op == '%' and isinstance(e.left, StrExpr):
+ if e.op == '%' and isinstance(e.left, (StrExpr, BytesExpr)):
return self.strfrm_checker.check_str_interpolation(cast(StrExpr, e.left), e.right)
left_type = self.accept(e.left)
diff --git a/mypy/checkstrformat.py b/mypy/checkstrformat.py
index 39e3fe468c7e..0b203e57faab 100644
--- a/mypy/checkstrformat.py
+++ b/mypy/checkstrformat.py
@@ -8,7 +8,7 @@
Type, AnyType, TupleType, Instance, UnionType
)
from mypy.nodes import (
- Node, StrExpr, TupleExpr, DictExpr, Context
+ Node, StrExpr, BytesExpr, TupleExpr, DictExpr, Context
)
if False:
# break import cycle only needed for mypy
@@ -136,7 +136,7 @@ def check_simple_str_interpolation(self, specifiers: List[ConversionSpecifier],
def check_mapping_str_interpolation(self, specifiers: List[ConversionSpecifier],
replacements: Node) -> None:
dict_with_only_str_literal_keys = (isinstance(replacements, DictExpr) and
- all(isinstance(k, StrExpr)
+ all(isinstance(k, (StrExpr, BytesExpr))
for k, v in cast(DictExpr, replacements).items))
if dict_with_only_str_literal_keys:
mapping = {} # type: Dict[str, Type]
@@ -255,7 +255,7 @@ def check_type(type: Type = None) -> None:
def check_node(node: Node) -> None:
"""int, or str with length 1"""
type = self.accept(node, expected_type)
- if isinstance(node, StrExpr) and len(cast(StrExpr, node).value) != 1:
+ if isinstance(node, (StrExpr, BytesExpr)) and len(cast(StrExpr, node).value) != 1:
self.msg.requires_int_or_char(context)
check_type(type)
diff --git a/mypy/exprtotype.py b/mypy/exprtotype.py
index c01bc15377d0..dc95f3d4ba02 100644
--- a/mypy/exprtotype.py
+++ b/mypy/exprtotype.py
@@ -1,7 +1,7 @@
"""Translate an expression (Node) to a Type value."""
from mypy.nodes import (
- Node, NameExpr, MemberExpr, IndexExpr, TupleExpr, ListExpr, StrExpr, EllipsisExpr
+ Node, NameExpr, MemberExpr, IndexExpr, TupleExpr, ListExpr, StrExpr, BytesExpr, EllipsisExpr
)
from mypy.parsetype import parse_str_as_type, TypeParseError
from mypy.types import Type, UnboundType, TypeList, EllipsisType
@@ -42,7 +42,7 @@ def expr_to_unanalyzed_type(expr: Node) -> Type:
elif isinstance(expr, ListExpr):
return TypeList([expr_to_unanalyzed_type(t) for t in expr.items],
line=expr.line)
- elif isinstance(expr, StrExpr):
+ elif isinstance(expr, (StrExpr, BytesExpr)):
# Parse string literal type.
try:
result = parse_str_as_type(expr.value, expr.line)
diff --git a/mypy/fastparse.py b/mypy/fastparse.py
index 0719174d73f7..072807086742 100644
--- a/mypy/fastparse.py
+++ b/mypy/fastparse.py
@@ -1,15 +1,15 @@
from functools import wraps
import sys
-from typing import Tuple, Union, TypeVar, Callable, Sequence
+from typing import Tuple, Union, TypeVar, Callable, Sequence, Optional, Any, cast, List
from mypy.nodes import (
- MypyFile, Import, ImportAll, ImportFrom, FuncDef, OverloadedFuncDef,
+ MypyFile, Node, ImportBase, Import, ImportAll, ImportFrom, FuncDef, OverloadedFuncDef,
ClassDef, Decorator, Block, Var, OperatorAssignmentStmt,
ExpressionStmt, AssignmentStmt, ReturnStmt, RaiseStmt, AssertStmt,
DelStmt, BreakStmt, ContinueStmt, PassStmt, GlobalDecl,
WhileStmt, ForStmt, IfStmt, TryStmt, WithStmt,
TupleExpr, GeneratorExpr, ListComprehension, ListExpr, ConditionalExpr,
- DictExpr, SetExpr, NameExpr, IntExpr, StrExpr, BytesExpr,
+ DictExpr, SetExpr, NameExpr, IntExpr, StrExpr, BytesExpr, UnicodeExpr,
FloatExpr, CallExpr, SuperExpr, MemberExpr, IndexExpr, SliceExpr, OpExpr,
UnaryExpr, FuncExpr, ComparisonExpr,
StarExpr, YieldFromExpr, NonlocalDecl, DictionaryComprehension,
@@ -21,7 +21,9 @@
from mypy.errors import Errors
try:
- import typed_ast # type: ignore
+ from typed_ast import ast27
+ from typed_ast import ast35
+ from typed_ast import conversions
except ImportError:
print('You must install the typed_ast module before you can run mypy with `--fast-parser`.\n'
'The typed_ast module can be found at https://github.com/ddfisher/typed_ast',
@@ -29,6 +31,7 @@
sys.exit(1)
T = TypeVar('T')
+U = TypeVar('U')
def parse(source: Union[str, bytes], fnam: str = None, errors: Errors = None,
@@ -43,7 +46,11 @@ def parse(source: Union[str, bytes], fnam: str = None, errors: Errors = None,
"""
is_stub_file = bool(fnam) and fnam.endswith('.pyi')
try:
- ast = typed_ast.parse(source, fnam, 'exec')
+ if pyversion[0] >= 3 or is_stub_file:
+ ast = ast35.parse(source, fnam, 'exec')
+ else:
+ ast2 = ast27.parse(source, fnam, 'exec')
+ ast = conversions.py2to3(ast2)
except SyntaxError as e:
if errors:
errors.set_file('' if fnam is None else fnam)
@@ -51,7 +58,9 @@ def parse(source: Union[str, bytes], fnam: str = None, errors: Errors = None,
else:
raise
else:
- tree = ASTConverter().visit(ast)
+ tree = ASTConverter(pyversion=pyversion,
+ custom_typing_module=custom_typing_module,
+ ).visit(ast)
tree.path = fnam
tree.is_stub = is_stub_file
return tree
@@ -64,11 +73,12 @@ def parse(source: Union[str, bytes], fnam: str = None, errors: Errors = None,
def parse_type_comment(type_comment: str, line: int) -> Type:
- typ = typed_ast.parse(type_comment, '', 'eval')
+ typ = ast35.parse(type_comment, '', 'eval')
+ assert isinstance(typ, ast35.Expression)
return TypeConverter(line=line).visit(typ.body)
-def with_line(f):
+def with_line(f: Callable[[Any, T], U]) -> Callable[[Any, T], U]:
@wraps(f)
def wrapper(self, ast):
node = f(self, ast)
@@ -84,37 +94,40 @@ def find(f: Callable[[T], bool], seq: Sequence[T]) -> T:
return None
-class ASTConverter(typed_ast.NodeTransformer):
- def __init__(self):
- self.in_class = False
- self.imports = []
+class ASTConverter(ast35.NodeTransformer):
+ def __init__(self, pyversion: Tuple[int, int], custom_typing_module: str = None) -> None:
+ self.class_nesting = 0
+ self.imports = [] # type: List[ImportBase]
+
+ self.pyversion = pyversion
+ self.custom_typing_module = custom_typing_module
- def generic_visit(self, node):
+ def generic_visit(self, node: ast35.AST) -> None:
raise RuntimeError('AST node not implemented: ' + str(type(node)))
- def visit_NoneType(self, n):
+ def visit_NoneType(self, n: Any) -> Optional[Node]:
return None
- def visit_list(self, l):
+ def visit_list(self, l: Sequence[ast35.AST]) -> List[Node]:
return [self.visit(e) for e in l]
op_map = {
- typed_ast.Add: '+',
- typed_ast.Sub: '-',
- typed_ast.Mult: '*',
- typed_ast.MatMult: '@',
- typed_ast.Div: '/',
- typed_ast.Mod: '%',
- typed_ast.Pow: '**',
- typed_ast.LShift: '<<',
- typed_ast.RShift: '>>',
- typed_ast.BitOr: '|',
- typed_ast.BitXor: '^',
- typed_ast.BitAnd: '&',
- typed_ast.FloorDiv: '//'
+ ast35.Add: '+',
+ ast35.Sub: '-',
+ ast35.Mult: '*',
+ ast35.MatMult: '@',
+ ast35.Div: '/',
+ ast35.Mod: '%',
+ ast35.Pow: '**',
+ ast35.LShift: '<<',
+ ast35.RShift: '>>',
+ ast35.BitOr: '|',
+ ast35.BitXor: '^',
+ ast35.BitAnd: '&',
+ ast35.FloorDiv: '//'
}
- def from_operator(self, op):
+ def from_operator(self, op: ast35.operator) -> str:
op_name = ASTConverter.op_map.get(type(op))
if op_name is None:
raise RuntimeError('Unknown operator ' + str(type(op)))
@@ -124,34 +137,34 @@ def from_operator(self, op):
return op_name
comp_op_map = {
- typed_ast.Gt: '>',
- typed_ast.Lt: '<',
- typed_ast.Eq: '==',
- typed_ast.GtE: '>=',
- typed_ast.LtE: '<=',
- typed_ast.NotEq: '!=',
- typed_ast.Is: 'is',
- typed_ast.IsNot: 'is not',
- typed_ast.In: 'in',
- typed_ast.NotIn: 'not in'
+ ast35.Gt: '>',
+ ast35.Lt: '<',
+ ast35.Eq: '==',
+ ast35.GtE: '>=',
+ ast35.LtE: '<=',
+ ast35.NotEq: '!=',
+ ast35.Is: 'is',
+ ast35.IsNot: 'is not',
+ ast35.In: 'in',
+ ast35.NotIn: 'not in'
}
- def from_comp_operator(self, op):
+ def from_comp_operator(self, op: ast35.cmpop) -> str:
op_name = ASTConverter.comp_op_map.get(type(op))
if op_name is None:
raise RuntimeError('Unknown comparison operator ' + str(type(op)))
else:
return op_name
- def as_block(self, stmts, lineno):
+ def as_block(self, stmts: List[ast35.stmt], lineno: int) -> Block:
b = None
if stmts:
- b = Block(self.visit(stmts))
+ b = Block(self.visit_list(stmts))
b.set_line(lineno)
return b
- def fix_function_overloads(self, stmts):
- ret = []
+ def fix_function_overloads(self, stmts: List[Node]) -> List[Node]:
+ ret = [] # type: List[Node]
current_overload = []
current_overload_name = None
# mypy doesn't actually check that the decorator is literally @overload
@@ -178,8 +191,24 @@ def fix_function_overloads(self, stmts):
ret.append(OverloadedFuncDef(current_overload))
return ret
- def visit_Module(self, mod):
- body = self.fix_function_overloads(self.visit(mod.body))
+ def in_class(self) -> bool:
+ return self.class_nesting > 0
+
+ def translate_module_id(self, id: str) -> str:
+ """Return the actual, internal module id for a source text id.
+
+ For example, translate '__builtin__' in Python 2 to 'builtins'.
+ """
+ if id == self.custom_typing_module:
+ return 'typing'
+ elif id == '__builtin__' and self.pyversion[0] == 2:
+ # HACK: __builtin__ in Python 2 is aliases to builtins. However, the implementation
+ # is named __builtin__.py (there is another layer of translation elsewhere).
+ return 'builtins'
+ return id
+
+ def visit_Module(self, mod: ast35.Module) -> Node:
+ body = self.fix_function_overloads(self.visit_list(mod.body))
return MypyFile(body,
self.imports,
@@ -193,19 +222,26 @@ def visit_Module(self, mod):
# arguments = (arg* args, arg? vararg, arg* kwonlyargs, expr* kw_defaults,
# arg? kwarg, expr* defaults)
@with_line
- def visit_FunctionDef(self, n):
+ def visit_FunctionDef(self, n: ast35.FunctionDef) -> Node:
args = self.transform_args(n.args, n.lineno)
arg_kinds = [arg.kind for arg in args]
arg_names = [arg.variable.name() for arg in args]
+ arg_types = None # type: List[Type]
if n.type_comment is not None:
- func_type_ast = typed_ast.parse(n.type_comment, '', 'func_type')
- arg_types = [a if a is not None else AnyType() for
- a in TypeConverter(line=n.lineno).visit(func_type_ast.argtypes)]
+ func_type_ast = ast35.parse(n.type_comment, '', 'func_type')
+ assert isinstance(func_type_ast, ast35.FunctionType)
+ # for ellipsis arg
+ if (len(func_type_ast.argtypes) == 1 and
+ isinstance(func_type_ast.argtypes[0], ast35.Ellipsis)):
+ arg_types = [AnyType() for a in args]
+ else:
+ arg_types = [a if a is not None else AnyType() for
+ a in TypeConverter(line=n.lineno).visit_list(func_type_ast.argtypes)]
return_type = TypeConverter(line=n.lineno).visit(func_type_ast.returns)
# add implicit self type
- if self.in_class and len(arg_types) < len(args):
+ if self.in_class() and len(arg_types) < len(args):
arg_types.insert(0, AnyType())
else:
arg_types = [a.type_annotation for a in args]
@@ -234,11 +270,11 @@ def visit_FunctionDef(self, n):
func_def.is_decorated = True
func_def.set_line(n.lineno + len(n.decorator_list))
func_def.body.set_line(func_def.get_line())
- return Decorator(func_def, self.visit(n.decorator_list), var)
+ return Decorator(func_def, self.visit_list(n.decorator_list), var)
else:
return func_def
- def transform_args(self, args, line):
+ def transform_args(self, args: ast35.arguments, line: int) -> List[Argument]:
def make_argument(arg, default, kind):
arg_type = TypeConverter(line=line).visit(arg.annotation)
return Argument(Var(arg.arg), arg_type, self.visit(default), kind)
@@ -275,10 +311,10 @@ def make_argument(arg, default, kind):
# TODO: AsyncFunctionDef(identifier name, arguments args,
# stmt* body, expr* decorator_list, expr? returns, string? type_comment)
- def stringify_name(self, n):
- if isinstance(n, typed_ast.Name):
+ def stringify_name(self, n: ast35.AST) -> str:
+ if isinstance(n, ast35.Name):
return n.id
- elif isinstance(n, typed_ast.Attribute):
+ elif isinstance(n, ast35.Attribute):
return "{}.{}".format(self.stringify_name(n.value), n.attr)
else:
assert False, "can't stringify " + str(type(n))
@@ -289,32 +325,32 @@ def stringify_name(self, n):
# stmt* body,
# expr* decorator_list)
@with_line
- def visit_ClassDef(self, n):
- self.in_class = True
+ def visit_ClassDef(self, n: ast35.ClassDef) -> Node:
+ self.class_nesting += 1
metaclass_arg = find(lambda x: x.arg == 'metaclass', n.keywords)
metaclass = None
if metaclass_arg:
metaclass = self.stringify_name(metaclass_arg.value)
cdef = ClassDef(n.name,
- Block(self.fix_function_overloads(self.visit(n.body))),
+ Block(self.fix_function_overloads(self.visit_list(n.body))),
None,
- self.visit(n.bases),
+ self.visit_list(n.bases),
metaclass=metaclass)
- cdef.decorators = self.visit(n.decorator_list)
- self.in_class = False
+ cdef.decorators = self.visit_list(n.decorator_list)
+ self.class_nesting -= 1
return cdef
# Return(expr? value)
@with_line
- def visit_Return(self, n):
+ def visit_Return(self, n: ast35.Return) -> Node:
return ReturnStmt(self.visit(n.value))
# Delete(expr* targets)
@with_line
- def visit_Delete(self, n):
+ def visit_Delete(self, n: ast35.Delete) -> Node:
if len(n.targets) > 1:
- tup = TupleExpr(self.visit(n.targets))
+ tup = TupleExpr(self.visit_list(n.targets))
tup.set_line(n.lineno)
return DelStmt(tup)
else:
@@ -322,25 +358,25 @@ def visit_Delete(self, n):
# Assign(expr* targets, expr value, string? type_comment)
@with_line
- def visit_Assign(self, n):
+ def visit_Assign(self, n: ast35.Assign) -> Node:
typ = None
if n.type_comment:
typ = parse_type_comment(n.type_comment, n.lineno)
- return AssignmentStmt(self.visit(n.targets),
+ return AssignmentStmt(self.visit_list(n.targets),
self.visit(n.value),
type=typ)
# AugAssign(expr target, operator op, expr value)
@with_line
- def visit_AugAssign(self, n):
+ def visit_AugAssign(self, n: ast35.AugAssign) -> Node:
return OperatorAssignmentStmt(self.from_operator(n.op),
self.visit(n.target),
self.visit(n.value))
# For(expr target, expr iter, stmt* body, stmt* orelse, string? type_comment)
@with_line
- def visit_For(self, n):
+ def visit_For(self, n: ast35.For) -> Node:
return ForStmt(self.visit(n.target),
self.visit(n.iter),
self.as_block(n.body, n.lineno),
@@ -349,21 +385,21 @@ def visit_For(self, n):
# TODO: AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
# While(expr test, stmt* body, stmt* orelse)
@with_line
- def visit_While(self, n):
+ def visit_While(self, n: ast35.While) -> Node:
return WhileStmt(self.visit(n.test),
self.as_block(n.body, n.lineno),
self.as_block(n.orelse, n.lineno))
# If(expr test, stmt* body, stmt* orelse)
@with_line
- def visit_If(self, n):
+ def visit_If(self, n: ast35.If) -> Node:
return IfStmt([self.visit(n.test)],
[self.as_block(n.body, n.lineno)],
self.as_block(n.orelse, n.lineno))
# With(withitem* items, stmt* body, string? type_comment)
@with_line
- def visit_With(self, n):
+ def visit_With(self, n: ast35.With) -> Node:
return WithStmt([self.visit(i.context_expr) for i in n.items],
[self.visit(i.optional_vars) for i in n.items],
self.as_block(n.body, n.lineno))
@@ -372,12 +408,12 @@ def visit_With(self, n):
# Raise(expr? exc, expr? cause)
@with_line
- def visit_Raise(self, n):
+ def visit_Raise(self, n: ast35.Raise) -> Node:
return RaiseStmt(self.visit(n.exc), self.visit(n.cause))
# Try(stmt* body, excepthandler* handlers, stmt* orelse, stmt* finalbody)
@with_line
- def visit_Try(self, n):
+ def visit_Try(self, n: ast35.Try) -> Node:
vs = [NameExpr(h.name) if h.name is not None else None for h in n.handlers]
types = [self.visit(h.type) for h in n.handlers]
handlers = [self.as_block(h.body, h.lineno) for h in n.handlers]
@@ -391,23 +427,24 @@ def visit_Try(self, n):
# Assert(expr test, expr? msg)
@with_line
- def visit_Assert(self, n):
+ def visit_Assert(self, n: ast35.Assert) -> Node:
return AssertStmt(self.visit(n.test))
# Import(alias* names)
@with_line
- def visit_Import(self, n):
- i = Import([(a.name, a.asname) for a in n.names])
+ def visit_Import(self, n: ast35.Import) -> Node:
+ i = Import([(self.translate_module_id(a.name), a.asname) for a in n.names])
self.imports.append(i)
return i
# ImportFrom(identifier? module, alias* names, int? level)
@with_line
- def visit_ImportFrom(self, n):
+ def visit_ImportFrom(self, n: ast35.ImportFrom) -> Node:
+ i = None # type: ImportBase
if len(n.names) == 1 and n.names[0].name == '*':
i = ImportAll(n.module, n.level)
else:
- i = ImportFrom(n.module if n.module is not None else '',
+ i = ImportFrom(self.translate_module_id(n.module) if n.module is not None else '',
n.level,
[(a.name, a.asname) for a in n.names])
self.imports.append(i)
@@ -415,45 +452,45 @@ def visit_ImportFrom(self, n):
# Global(identifier* names)
@with_line
- def visit_Global(self, n):
+ def visit_Global(self, n: ast35.Global) -> Node:
return GlobalDecl(n.names)
# Nonlocal(identifier* names)
@with_line
- def visit_Nonlocal(self, n):
+ def visit_Nonlocal(self, n: ast35.Nonlocal) -> Node:
return NonlocalDecl(n.names)
# Expr(expr value)
@with_line
- def visit_Expr(self, expr):
- value = self.visit(expr.value)
+ def visit_Expr(self, n: ast35.Expr) -> Node:
+ value = self.visit(n.value)
return ExpressionStmt(value)
# Pass
@with_line
- def visit_Pass(self, n):
+ def visit_Pass(self, n: ast35.Pass) -> Node:
return PassStmt()
# Break
@with_line
- def visit_Break(self, n):
+ def visit_Break(self, n: ast35.Break) -> Node:
return BreakStmt()
# Continue
@with_line
- def visit_Continue(self, n):
+ def visit_Continue(self, n: ast35.Continue) -> Node:
return ContinueStmt()
# --- expr ---
# BoolOp(boolop op, expr* values)
@with_line
- def visit_BoolOp(self, n):
+ def visit_BoolOp(self, n: ast35.BoolOp) -> Node:
# mypy translates (1 and 2 and 3) as (1 and (2 and 3))
assert len(n.values) >= 2
op = None
- if isinstance(n.op, typed_ast.And):
+ if isinstance(n.op, ast35.And):
op = 'and'
- elif isinstance(n.op, typed_ast.Or):
+ elif isinstance(n.op, ast35.Or):
op = 'or'
else:
raise RuntimeError('unknown BoolOp ' + str(type(n)))
@@ -465,11 +502,11 @@ def group(vals):
else:
return OpExpr(op, vals[0], group(vals[1:]))
- return group(self.visit(n.values))
+ return group(self.visit_list(n.values))
# BinOp(expr left, operator op, expr right)
@with_line
- def visit_BinOp(self, n):
+ def visit_BinOp(self, n: ast35.BinOp) -> Node:
op = self.from_operator(n.op)
if op is None:
@@ -479,15 +516,15 @@ def visit_BinOp(self, n):
# UnaryOp(unaryop op, expr operand)
@with_line
- def visit_UnaryOp(self, n):
+ def visit_UnaryOp(self, n: ast35.UnaryOp) -> Node:
op = None
- if isinstance(n.op, typed_ast.Invert):
+ if isinstance(n.op, ast35.Invert):
op = '~'
- elif isinstance(n.op, typed_ast.Not):
+ elif isinstance(n.op, ast35.Not):
op = 'not'
- elif isinstance(n.op, typed_ast.UAdd):
+ elif isinstance(n.op, ast35.UAdd):
op = '+'
- elif isinstance(n.op, typed_ast.USub):
+ elif isinstance(n.op, ast35.USub):
op = '-'
if op is None:
@@ -497,8 +534,8 @@ def visit_UnaryOp(self, n):
# Lambda(arguments args, expr body)
@with_line
- def visit_Lambda(self, n):
- body = typed_ast.Return(n.body)
+ def visit_Lambda(self, n: ast35.Lambda) -> Node:
+ body = ast35.Return(n.body)
body.lineno = n.lineno
return FuncExpr(self.transform_args(n.args, n.lineno),
@@ -506,37 +543,37 @@ def visit_Lambda(self, n):
# IfExp(expr test, expr body, expr orelse)
@with_line
- def visit_IfExp(self, n):
+ def visit_IfExp(self, n: ast35.IfExp) -> Node:
return ConditionalExpr(self.visit(n.test),
self.visit(n.body),
self.visit(n.orelse))
# Dict(expr* keys, expr* values)
@with_line
- def visit_Dict(self, n):
- return DictExpr(list(zip(self.visit(n.keys), self.visit(n.values))))
+ def visit_Dict(self, n: ast35.Dict) -> Node:
+ return DictExpr(list(zip(self.visit_list(n.keys), self.visit_list(n.values))))
# Set(expr* elts)
@with_line
- def visit_Set(self, n):
- return SetExpr(self.visit(n.elts))
+ def visit_Set(self, n: ast35.Set) -> Node:
+ return SetExpr(self.visit_list(n.elts))
# ListComp(expr elt, comprehension* generators)
@with_line
- def visit_ListComp(self, n):
- return ListComprehension(self.visit_GeneratorExp(n))
+ def visit_ListComp(self, n: ast35.ListComp) -> Node:
+ return ListComprehension(self.visit_GeneratorExp(cast(ast35.GeneratorExp, n)))
# SetComp(expr elt, comprehension* generators)
@with_line
- def visit_SetComp(self, n):
- return SetComprehension(self.visit_GeneratorExp(n))
+ def visit_SetComp(self, n: ast35.SetComp) -> Node:
+ return SetComprehension(self.visit_GeneratorExp(cast(ast35.GeneratorExp, n)))
# DictComp(expr key, expr value, comprehension* generators)
@with_line
- def visit_DictComp(self, n):
+ def visit_DictComp(self, n: ast35.DictComp) -> Node:
targets = [self.visit(c.target) for c in n.generators]
iters = [self.visit(c.iter) for c in n.generators]
- ifs_list = [self.visit(c.ifs) for c in n.generators]
+ ifs_list = [self.visit_list(c.ifs) for c in n.generators]
return DictionaryComprehension(self.visit(n.key),
self.visit(n.value),
targets,
@@ -545,10 +582,10 @@ def visit_DictComp(self, n):
# GeneratorExp(expr elt, comprehension* generators)
@with_line
- def visit_GeneratorExp(self, n):
+ def visit_GeneratorExp(self, n: ast35.GeneratorExp) -> GeneratorExpr:
targets = [self.visit(c.target) for c in n.generators]
iters = [self.visit(c.iter) for c in n.generators]
- ifs_list = [self.visit(c.ifs) for c in n.generators]
+ ifs_list = [self.visit_list(c.ifs) for c in n.generators]
return GeneratorExpr(self.visit(n.elt),
targets,
iters,
@@ -558,77 +595,75 @@ def visit_GeneratorExp(self, n):
# Yield(expr? value)
@with_line
- def visit_Yield(self, n):
+ def visit_Yield(self, n: ast35.Yield) -> Node:
return YieldExpr(self.visit(n.value))
# YieldFrom(expr value)
@with_line
- def visit_YieldFrom(self, n):
+ def visit_YieldFrom(self, n: ast35.YieldFrom) -> Node:
return YieldFromExpr(self.visit(n.value))
# Compare(expr left, cmpop* ops, expr* comparators)
@with_line
- def visit_Compare(self, n):
+ def visit_Compare(self, n: ast35.Compare) -> Node:
operators = [self.from_comp_operator(o) for o in n.ops]
- operands = self.visit([n.left] + n.comparators)
+ operands = self.visit_list([n.left] + n.comparators)
return ComparisonExpr(operators, operands)
# Call(expr func, expr* args, keyword* keywords)
# keyword = (identifier? arg, expr value)
@with_line
- def visit_Call(self, n):
- def is_stararg(a):
- return isinstance(a, typed_ast.Starred)
-
+ def visit_Call(self, n: ast35.Call) -> Node:
def is_star2arg(k):
return k.arg is None
- arg_types = self.visit([a.value if is_stararg(a) else a for a in n.args] +
- [k.value for k in n.keywords])
- arg_kinds = ([ARG_STAR if is_stararg(a) else ARG_POS for a in n.args] +
+ arg_types = self.visit_list(
+ [a.value if isinstance(a, ast35.Starred) else a for a in n.args] +
+ [k.value for k in n.keywords])
+ arg_kinds = ([ARG_STAR if isinstance(a, ast35.Starred) else ARG_POS for a in n.args] +
[ARG_STAR2 if is_star2arg(k) else ARG_NAMED for k in n.keywords])
return CallExpr(self.visit(n.func),
arg_types,
arg_kinds,
- [None for _ in n.args] + [k.arg for k in n.keywords])
+ cast("List[str]", [None for _ in n.args]) + [k.arg for k in n.keywords])
# Num(object n) -- a number as a PyObject.
@with_line
- def visit_Num(self, num):
- if isinstance(num.n, int):
- return IntExpr(num.n)
- elif isinstance(num.n, float):
- return FloatExpr(num.n)
- elif isinstance(num.n, complex):
- return ComplexExpr(num.n)
+ def visit_Num(self, n: ast35.Num) -> Node:
+ if isinstance(n.n, int):
+ return IntExpr(n.n)
+ elif isinstance(n.n, float):
+ return FloatExpr(n.n)
+ elif isinstance(n.n, complex):
+ return ComplexExpr(n.n)
- raise RuntimeError('num not implemented for ' + str(type(num.n)))
+ raise RuntimeError('num not implemented for ' + str(type(n.n)))
# Str(string s) -- need to specify raw, unicode, etc?
@with_line
- def visit_Str(self, n):
+ def visit_Str(self, n: ast35.Str) -> Node:
return StrExpr(n.s)
# Bytes(bytes s)
@with_line
- def visit_Bytes(self, n):
+ def visit_Bytes(self, n: ast35.Bytes) -> Node:
# TODO: this is kind of hacky
return BytesExpr(str(n.s)[2:-1])
# NameConstant(singleton value)
- def visit_NameConstant(self, n):
+ def visit_NameConstant(self, n: ast35.NameConstant) -> Node:
return NameExpr(str(n.value))
# Ellipsis
@with_line
- def visit_Ellipsis(self, n):
+ def visit_Ellipsis(self, n: ast35.Ellipsis) -> Node:
return EllipsisExpr()
# Attribute(expr value, identifier attr, expr_context ctx)
@with_line
- def visit_Attribute(self, n):
- if (isinstance(n.value, typed_ast.Call) and
- isinstance(n.value.func, typed_ast.Name) and
+ def visit_Attribute(self, n: ast35.Attribute) -> Node:
+ if (isinstance(n.value, ast35.Call) and
+ isinstance(n.value.func, ast35.Name) and
n.value.func.id == 'super'):
return SuperExpr(n.attr)
@@ -636,90 +671,90 @@ def visit_Attribute(self, n):
# Subscript(expr value, slice slice, expr_context ctx)
@with_line
- def visit_Subscript(self, n):
+ def visit_Subscript(self, n: ast35.Subscript) -> Node:
return IndexExpr(self.visit(n.value), self.visit(n.slice))
# Starred(expr value, expr_context ctx)
@with_line
- def visit_Starred(self, n):
+ def visit_Starred(self, n: ast35.Starred) -> Node:
return StarExpr(self.visit(n.value))
# Name(identifier id, expr_context ctx)
@with_line
- def visit_Name(self, n):
+ def visit_Name(self, n: ast35.Name) -> Node:
return NameExpr(n.id)
# List(expr* elts, expr_context ctx)
@with_line
- def visit_List(self, n):
+ def visit_List(self, n: ast35.List) -> Node:
return ListExpr([self.visit(e) for e in n.elts])
# Tuple(expr* elts, expr_context ctx)
@with_line
- def visit_Tuple(self, n):
+ def visit_Tuple(self, n: ast35.Tuple) -> Node:
return TupleExpr([self.visit(e) for e in n.elts])
# --- slice ---
# Slice(expr? lower, expr? upper, expr? step)
- def visit_Slice(self, n):
+ def visit_Slice(self, n: ast35.Slice) -> Node:
return SliceExpr(self.visit(n.lower),
self.visit(n.upper),
self.visit(n.step))
# ExtSlice(slice* dims)
- def visit_ExtSlice(self, n):
- return TupleExpr(self.visit(n.dims))
+ def visit_ExtSlice(self, n: ast35.ExtSlice) -> Node:
+ return TupleExpr(self.visit_list(n.dims))
# Index(expr value)
- def visit_Index(self, n):
+ def visit_Index(self, n: ast35.Index) -> Node:
return self.visit(n.value)
-class TypeConverter(typed_ast.NodeTransformer):
- def __init__(self, line=-1):
+class TypeConverter(ast35.NodeTransformer):
+ def __init__(self, line: int = -1) -> None:
self.line = line
- def generic_visit(self, node):
+ def generic_visit(self, node: ast35.AST) -> None:
raise RuntimeError('Type node not implemented: ' + str(type(node)))
- def visit_NoneType(self, n):
+ def visit_NoneType(self, n: Any) -> Type:
return None
- def visit_list(self, l):
+ def visit_list(self, l: Sequence[ast35.AST]) -> List[Type]:
return [self.visit(e) for e in l]
- def visit_Name(self, n):
+ def visit_Name(self, n: ast35.Name) -> Type:
return UnboundType(n.id, line=self.line)
- def visit_NameConstant(self, n):
+ def visit_NameConstant(self, n: ast35.NameConstant) -> Type:
return UnboundType(str(n.value))
# Str(string s)
- def visit_Str(self, n):
+ def visit_Str(self, n: ast35.Str) -> Type:
return parse_type_comment(n.s.strip(), line=self.line)
# Subscript(expr value, slice slice, expr_context ctx)
- def visit_Subscript(self, n):
- assert isinstance(n.slice, typed_ast.Index)
+ def visit_Subscript(self, n: ast35.Subscript) -> Type:
+ assert isinstance(n.slice, ast35.Index)
value = self.visit(n.value)
assert isinstance(value, UnboundType)
assert not value.args
- if isinstance(n.slice.value, typed_ast.Tuple):
- params = self.visit(n.slice.value.elts)
+ if isinstance(n.slice.value, ast35.Tuple):
+ params = self.visit_list(n.slice.value.elts)
else:
params = [self.visit(n.slice.value)]
return UnboundType(value.name, params, line=self.line)
- def visit_Tuple(self, n):
- return TupleType(self.visit(n.elts), None, implicit=True, line=self.line)
+ def visit_Tuple(self, n: ast35.Tuple) -> Type:
+ return TupleType(self.visit_list(n.elts), None, implicit=True, line=self.line)
# Attribute(expr value, identifier attr, expr_context ctx)
- def visit_Attribute(self, n):
+ def visit_Attribute(self, n: ast35.Attribute) -> Type:
before_dot = self.visit(n.value)
assert isinstance(before_dot, UnboundType)
@@ -728,9 +763,9 @@ def visit_Attribute(self, n):
return UnboundType("{}.{}".format(before_dot.name, n.attr), line=self.line)
# Ellipsis
- def visit_Ellipsis(self, n):
+ def visit_Ellipsis(self, n: ast35.Ellipsis) -> Type:
return EllipsisType(line=self.line)
# List(expr* elts, expr_context ctx)
- def visit_List(self, n):
- return TypeList(self.visit(n.elts), line=self.line)
+ def visit_List(self, n: ast35.List) -> Type:
+ return TypeList(self.visit_list(n.elts), line=self.line)
diff --git a/mypy/main.py b/mypy/main.py
index 1cc3306f0893..40a279601bc8 100644
--- a/mypy/main.py
+++ b/mypy/main.py
@@ -199,10 +199,6 @@ def parse_version(v):
parser.error('Python version 2 (or --py2) specified, '
'but --use-python-path will search in sys.path of Python 3')
- if args.fast_parser and args.python_version and args.python_version[0] == 2:
- parser.error('The experimental fast parser is only compatible with Python 3, '
- 'but Python 2 specified.')
-
# Set options.
options = Options()
options.dirty_stubs = args.dirty_stubs
diff --git a/mypy/semanal.py b/mypy/semanal.py
index 3146643aa549..385d9d5edd73 100644
--- a/mypy/semanal.py
+++ b/mypy/semanal.py
@@ -58,7 +58,7 @@
SliceExpr, CastExpr, TypeApplication, Context, SymbolTable,
SymbolTableNode, BOUND_TVAR, UNBOUND_TVAR, ListComprehension, GeneratorExpr,
FuncExpr, MDEF, FuncBase, Decorator, SetExpr, TypeVarExpr,
- StrExpr, PrintStmt, ConditionalExpr, PromoteExpr,
+ StrExpr, BytesExpr, PrintStmt, ConditionalExpr, PromoteExpr,
ComparisonExpr, StarExpr, ARG_POS, ARG_NAMED, MroError, type_aliases,
YieldFromExpr, NamedTupleExpr, NonlocalDecl,
SetComprehension, DictionaryComprehension, TYPE_ALIAS, TypeAliasExpr,
@@ -1279,7 +1279,7 @@ def check_typevar_name(self, call: CallExpr, name: str, context: Context) -> boo
if len(call.args) < 1:
self.fail("Too few arguments for TypeVar()", context)
return False
- if not isinstance(call.args[0], StrExpr) or not call.arg_kinds[0] == ARG_POS:
+ if not isinstance(call.args[0], (StrExpr, BytesExpr)) or not call.arg_kinds[0] == ARG_POS:
self.fail("TypeVar() expects a string literal as first argument", context)
return False
if cast(StrExpr, call.args[0]).value != name:
@@ -1425,13 +1425,13 @@ def parse_namedtuple_args(self, call: CallExpr,
return self.fail_namedtuple_arg("Too many arguments for namedtuple()", call)
if call.arg_kinds != [ARG_POS, ARG_POS]:
return self.fail_namedtuple_arg("Unexpected arguments to namedtuple()", call)
- if not isinstance(args[0], StrExpr):
+ if not isinstance(args[0], (StrExpr, BytesExpr)):
return self.fail_namedtuple_arg(
"namedtuple() expects a string literal as the first argument", call)
types = [] # type: List[Type]
ok = True
if not isinstance(args[1], ListExpr):
- if fullname == 'collections.namedtuple' and isinstance(args[1], StrExpr):
+ if fullname == 'collections.namedtuple' and isinstance(args[1], (StrExpr, BytesExpr)):
str_expr = cast(StrExpr, args[1])
items = str_expr.value.split()
else:
@@ -1441,7 +1441,7 @@ def parse_namedtuple_args(self, call: CallExpr,
listexpr = cast(ListExpr, args[1])
if fullname == 'collections.namedtuple':
# The fields argument contains just names, with implicit Any types.
- if any(not isinstance(item, StrExpr) for item in listexpr.items):
+ if any(not isinstance(item, (StrExpr, BytesExpr)) for item in listexpr.items):
return self.fail_namedtuple_arg("String literal expected as namedtuple() item",
call)
items = [cast(StrExpr, item).value for item in listexpr.items]
@@ -1462,7 +1462,7 @@ def parse_namedtuple_fields_with_types(self, nodes: List[Node],
return self.fail_namedtuple_arg("Invalid NamedTuple field definition",
item)
name, type_node = item.items
- if isinstance(name, StrExpr):
+ if isinstance(name, (StrExpr, BytesExpr)):
items.append(name.value)
else:
return self.fail_namedtuple_arg("Invalid NamedTuple() field name", item)