|
1 | 1 | """Expression type checker. This file is conceptually part of TypeChecker."""
|
2 | 2 |
|
3 |
| -from typing import cast, List, Tuple, Callable, Union, Optional |
| 3 | +from typing import cast, Dict, List, Tuple, Callable, Union, Optional |
4 | 4 |
|
5 | 5 | from mypy.types import (
|
6 | 6 | Type, AnyType, CallableType, Overloaded, NoneTyp, Void, TypeVarDef,
|
@@ -1415,45 +1415,37 @@ def visit_conditional_expr(self, e: ConditionalExpr) -> Type:
|
1415 | 1415 | self.chk.type_map,
|
1416 | 1416 | self.chk.typing_mode_weak())
|
1417 | 1417 |
|
1418 |
| - with self.chk.binder: |
1419 |
| - if if_map: |
1420 |
| - for var, type in if_map.items(): |
1421 |
| - self.chk.binder.push(var, type) |
1422 |
| - if_type = self.accept(e.if_expr, context=ctx) |
| 1418 | + if_type = self.analyze_cond_branch(if_map, e.if_expr, context=ctx) |
1423 | 1419 |
|
1424 | 1420 | if not mypy.checker.is_valid_inferred_type(if_type):
|
1425 | 1421 | # Analyze the right branch disregarding the left branch.
|
1426 |
| - with self.chk.binder: |
1427 |
| - if else_map: |
1428 |
| - for var, type in else_map.items(): |
1429 |
| - self.chk.binder.push(var, type) |
1430 |
| - else_type = self.accept(e.else_expr, context=ctx) |
| 1422 | + else_type = self.analyze_cond_branch(else_map, e.else_expr, context=ctx) |
1431 | 1423 |
|
1432 | 1424 | # If it would make a difference, re-analyze the left
|
1433 | 1425 | # branch using the right branch's type as context.
|
1434 | 1426 | if ctx is None or not is_equivalent(else_type, ctx):
|
1435 | 1427 | # TODO: If it's possible that the previous analysis of
|
1436 | 1428 | # the left branch produced errors that are avoided
|
1437 | 1429 | # using this context, suppress those errors.
|
1438 |
| - with self.chk.binder: |
1439 |
| - if if_map: |
1440 |
| - for var, type in if_map.items(): |
1441 |
| - self.chk.binder.push(var, type) |
1442 |
| - if_type = self.accept(e.if_expr, context=else_type) |
| 1430 | + if_type = self.analyze_cond_branch(if_map, e.if_expr, context=else_type) |
1443 | 1431 |
|
1444 | 1432 | else:
|
1445 | 1433 | # Analyze the right branch in the context of the left
|
1446 | 1434 | # branch's type.
|
1447 |
| - with self.chk.binder: |
1448 |
| - if else_map: |
1449 |
| - for var, type in else_map.items(): |
1450 |
| - self.chk.binder.push(var, type) |
1451 |
| - else_type = self.accept(e.else_expr, context=if_type) |
| 1435 | + else_type = self.analyze_cond_branch(else_map, e.else_expr, context=if_type) |
1452 | 1436 |
|
1453 | 1437 | res = join.join_types(if_type, else_type)
|
1454 | 1438 |
|
1455 | 1439 | return res
|
1456 | 1440 |
|
| 1441 | + def analyze_cond_branch(self, map: Optional[Dict[Node, Type]], |
| 1442 | + node: Node, context: Optional[Type]) -> Type: |
| 1443 | + with self.chk.binder: |
| 1444 | + if map: |
| 1445 | + for var, type in map.items(): |
| 1446 | + self.chk.binder.push(var, type) |
| 1447 | + return self.accept(node, context=context) |
| 1448 | + |
1457 | 1449 | def visit_backquote_expr(self, e: BackquoteExpr) -> Type:
|
1458 | 1450 | self.accept(e.expr)
|
1459 | 1451 | return self.named_type('builtins.str')
|
|
0 commit comments