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

Tighten types for semanal #2207

Merged
merged 5 commits into from
Oct 2, 2016
Merged
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions mypy/nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ def accept(self, visitor: NodeVisitor[T]) -> T:
# fields of Node subtypes are expected to contain.
Statement = Node
Expression = Node
Lvalue = Expression


class SymbolNode(Node):
Expand Down
52 changes: 27 additions & 25 deletions mypy/semanal.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@

from mypy.nodes import (
MypyFile, TypeInfo, Node, AssignmentStmt, FuncDef, OverloadedFuncDef,
ClassDef, Var, GDEF, MODULE_REF, FuncItem, Import,
ClassDef, Var, GDEF, MODULE_REF, FuncItem, Import, Expression, Lvalue,
ImportFrom, ImportAll, Block, LDEF, NameExpr, MemberExpr,
IndexExpr, TupleExpr, ListExpr, ExpressionStmt, ReturnStmt,
RaiseStmt, AssertStmt, OperatorAssignmentStmt, WhileStmt,
Expand Down Expand Up @@ -405,7 +405,7 @@ def find_type_variables_in_type(
assert False, 'Unsupported type %s' % type
return result

def is_defined_type_var(self, tvar: str, context: Node) -> bool:
def is_defined_type_var(self, tvar: str, context: Context) -> bool:
return self.lookup_qualified(tvar, context).kind == BOUND_TVAR

def visit_overloaded_func_def(self, defn: OverloadedFuncDef) -> None:
Expand Down Expand Up @@ -606,7 +606,7 @@ def unbind_class_type_vars(self) -> None:
if self.bound_tvars:
enable_typevars(self.bound_tvars)

def analyze_class_decorator(self, defn: ClassDef, decorator: Node) -> None:
def analyze_class_decorator(self, defn: ClassDef, decorator: Expression) -> None:
decorator.accept(self)

def setup_is_builtinclass(self, defn: ClassDef) -> None:
Expand Down Expand Up @@ -801,7 +801,7 @@ def analyze_base_classes(self, defn: ClassDef) -> None:
if info.mro and info.mro[-1].fullname() != 'builtins.object':
info.mro.append(self.object_type().type)

def expr_to_analyzed_type(self, expr: Node) -> Type:
def expr_to_analyzed_type(self, expr: Expression) -> Type:
if isinstance(expr, CallExpr):
expr.accept(self)
info = self.check_namedtuple(expr)
Expand Down Expand Up @@ -1135,7 +1135,7 @@ def visit_assignment_stmt(self, s: AssignmentStmt) -> None:
isinstance(s.rvalue, (ListExpr, TupleExpr))):
self.add_exports(*s.rvalue.items)

def analyze_simple_literal_type(self, rvalue: Node) -> Optional[Type]:
def analyze_simple_literal_type(self, rvalue: Expression) -> Optional[Type]:
"""Return builtins.int if rvalue is an int literal, etc."""
if self.weak_opts or self.options.semantic_analysis_only or self.function_stack:
# Skip this if any weak options are set.
Expand Down Expand Up @@ -1177,7 +1177,7 @@ def check_and_set_up_type_alias(self, s: AssignmentStmt) -> None:
# just an alias for the type.
self.globals[lvalue.name].node = node

def analyze_lvalue(self, lval: Node, nested: bool = False,
def analyze_lvalue(self, lval: Lvalue, nested: bool = False,
add_global: bool = False,
explicit_type: bool = False) -> None:
"""Analyze an lvalue or assignment target.
Expand Down Expand Up @@ -1300,11 +1300,11 @@ def is_self_member_ref(self, memberexpr: MemberExpr) -> bool:
node = memberexpr.expr.node
return isinstance(node, Var) and node.is_self

def check_lvalue_validity(self, node: Node, ctx: Context) -> None:
def check_lvalue_validity(self, node: Expression, ctx: Context) -> None:
if isinstance(node, (TypeInfo, TypeVarExpr)):
self.fail('Invalid assignment target', ctx)

def store_declared_types(self, lvalue: Node, typ: Type) -> None:
def store_declared_types(self, lvalue: Lvalue, typ: Type) -> None:
if isinstance(typ, StarType) and not isinstance(lvalue, StarExpr):
self.fail('Star type only allowed for starred expressions', lvalue)
if isinstance(lvalue, RefExpr):
Expand Down Expand Up @@ -1508,7 +1508,7 @@ def get_typevar_declaration(self, s: AssignmentStmt) -> Optional[CallExpr]:
return None
return call

def process_typevar_parameters(self, args: List[Node],
def process_typevar_parameters(self, args: List[Expression],
names: List[Optional[str]],
kinds: List[int],
has_values: bool,
Expand Down Expand Up @@ -1585,7 +1585,7 @@ def process_namedtuple_definition(self, s: AssignmentStmt) -> None:
# TODO call.analyzed
node.node = named_tuple

def check_namedtuple(self, node: Node, var_name: str = None) -> TypeInfo:
def check_namedtuple(self, node: Expression, var_name: str = None) -> TypeInfo:
"""Check if a call defines a namedtuple.
The optional var_name argument is the name of the variable to
Expand Down Expand Up @@ -1665,7 +1665,7 @@ def parse_namedtuple_args(self, call: CallExpr,
+ ', '.join(underscore), call)
return items, types, ok

def parse_namedtuple_fields_with_types(self, nodes: List[Node],
def parse_namedtuple_fields_with_types(self, nodes: List[Expression],
context: Context) -> Tuple[List[str], List[Type], bool]:
items = [] # type: List[str]
types = [] # type: List[Type]
Expand Down Expand Up @@ -1770,7 +1770,7 @@ def add_method(funcname: str, ret: Type, args: List[Argument], name=None,
def make_argument(self, name: str, type: Type) -> Argument:
return Argument(Var(name), type, None, ARG_POS)

def analyze_types(self, items: List[Node]) -> List[Type]:
def analyze_types(self, items: List[Expression]) -> List[Type]:
result = [] # type: List[Type]
for node in items:
try:
Expand Down Expand Up @@ -1931,7 +1931,7 @@ def visit_del_stmt(self, s: DelStmt) -> None:
if not self.is_valid_del_target(s.expr):
self.fail('Invalid delete target', s)

def is_valid_del_target(self, s: Node) -> bool:
def is_valid_del_target(self, s: Expression) -> bool:
if isinstance(s, (IndexExpr, NameExpr, MemberExpr)):
return True
elif isinstance(s, TupleExpr):
Expand Down Expand Up @@ -2502,7 +2502,7 @@ def add_local(self, node: Union[Var, FuncBase], ctx: Context) -> None:
node._fullname = name
self.locals[-1][name] = SymbolTableNode(LDEF, node)

def add_exports(self, *exps: Node) -> None:
def add_exports(self, *exps: Expression) -> None:
for exp in exps:
if isinstance(exp, StrExpr):
self.all_exports.add(exp.value)
Expand Down Expand Up @@ -2753,7 +2753,7 @@ def visit_if_stmt(self, s: IfStmt) -> None:
def visit_try_stmt(self, s: TryStmt) -> None:
self.sem.analyze_try_stmt(s, self, add_global=True)

def analyze_lvalue(self, lvalue: Node, explicit_type: bool = False) -> None:
def analyze_lvalue(self, lvalue: Lvalue, explicit_type: bool = False) -> None:
self.sem.analyze_lvalue(lvalue, add_global=True, explicit_type=explicit_type)


Expand Down Expand Up @@ -2919,12 +2919,12 @@ def set_callable_name(sig: Type, fdef: FuncDef) -> Type:
return sig


def refers_to_fullname(node: Node, fullname: str) -> bool:
def refers_to_fullname(node: Expression, fullname: str) -> bool:
"""Is node a name or member expression with the given full name?"""
return isinstance(node, RefExpr) and node.fullname == fullname


def refers_to_class_or_function(node: Node) -> bool:
def refers_to_class_or_function(node: Expression) -> bool:
"""Does semantically analyzed node refer to a class?"""
return (isinstance(node, RefExpr) and
isinstance(node.node, (TypeInfo, FuncDef, OverloadedFuncDef)))
Expand Down Expand Up @@ -2997,7 +2997,7 @@ def infer_reachability_of_if_statement(s: IfStmt,
break


def infer_if_condition_value(expr: Node, pyversion: Tuple[int, int], platform: str) -> int:
def infer_if_condition_value(expr: Expression, pyversion: Tuple[int, int], platform: str) -> int:
"""Infer whether if condition is always true/false.
Return ALWAYS_TRUE if always true, ALWAYS_FALSE if always false,
Expand Down Expand Up @@ -3034,7 +3034,7 @@ def infer_if_condition_value(expr: Node, pyversion: Tuple[int, int], platform: s
return result


def consider_sys_version_info(expr: Node, pyversion: Tuple[int, ...]) -> int:
def consider_sys_version_info(expr: Expression, pyversion: Tuple[int, ...]) -> int:
"""Consider whether expr is a comparison involving sys.version_info.
Return ALWAYS_TRUE, ALWAYS_FALSE, or TRUTH_VALUE_UNKNOWN.
Expand Down Expand Up @@ -3076,7 +3076,7 @@ def consider_sys_version_info(expr: Node, pyversion: Tuple[int, ...]) -> int:
return TRUTH_VALUE_UNKNOWN


def consider_sys_platform(expr: Node, platform: str) -> int:
def consider_sys_platform(expr: Expression, platform: str) -> int:
"""Consider whether expr is a comparison involving sys.platform.
Return ALWAYS_TRUE, ALWAYS_FALSE, or TRUTH_VALUE_UNKNOWN.
Expand Down Expand Up @@ -3135,7 +3135,8 @@ def fixed_comparison(left: Targ, op: str, right: Targ) -> int:
return TRUTH_VALUE_UNKNOWN


def contains_int_or_tuple_of_ints(expr: Node) -> Union[None, int, Tuple[int], Tuple[int, ...]]:
def contains_int_or_tuple_of_ints(expr: Expression
) -> Union[None, int, Tuple[int], Tuple[int, ...]]:
if isinstance(expr, IntExpr):
return expr.value
if isinstance(expr, TupleExpr):
Expand All @@ -3149,7 +3150,8 @@ def contains_int_or_tuple_of_ints(expr: Node) -> Union[None, int, Tuple[int], Tu
return None


def contains_sys_version_info(expr: Node) -> Union[None, int, Tuple[Optional[int], Optional[int]]]:
def contains_sys_version_info(expr: Expression
) -> Union[None, int, Tuple[Optional[int], Optional[int]]]:
if is_sys_attr(expr, 'version_info'):
return (None, None) # Same as sys.version_info[:]
if isinstance(expr, IndexExpr) and is_sys_attr(expr.base, 'version_info'):
Expand All @@ -3173,7 +3175,7 @@ def contains_sys_version_info(expr: Node) -> Union[None, int, Tuple[Optional[int
return None


def is_sys_attr(expr: Node, name: str) -> bool:
def is_sys_attr(expr: Expression, name: str) -> bool:
# TODO: This currently doesn't work with code like this:
# - import sys as _sys
# - from sys import version_info
Expand Down Expand Up @@ -3211,7 +3213,7 @@ def is_identity_signature(sig: Type) -> bool:
return False


def returns_any_if_called(expr: Node) -> bool:
def returns_any_if_called(expr: Expression) -> bool:
"""Return True if we can predict that expr will return Any if called.
This only uses information available during semantic analysis so this
Expand All @@ -3234,7 +3236,7 @@ def returns_any_if_called(expr: Node) -> bool:
return False


def find_fixed_callable_return(expr: Node) -> Optional[CallableType]:
def find_fixed_callable_return(expr: Expression) -> Optional[CallableType]:
if isinstance(expr, RefExpr):
if isinstance(expr.node, FuncDef):
typ = expr.node.type
Expand Down