Skip to content

Commit a877957

Browse files
committed
Fix merge and sync with python#4072
1 parent 46e8c2d commit a877957

File tree

2 files changed

+30
-17
lines changed

2 files changed

+30
-17
lines changed

mypy/checker.py

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
from mypy.erasetype import erase_typevars
5454
from mypy.expandtype import expand_type, expand_type_by_instance
5555
from mypy.visitor import NodeVisitor
56-
from mypy.join import join_types, join_type_list
56+
from mypy.join import join_types
5757
from mypy.treetransform import TransformVisitor
5858
from mypy.binder import ConditionalTypeBinder, get_declaration
5959
from mypy.meet import is_overlapping_types
@@ -2957,12 +2957,12 @@ def builtin_item_type(tp: Type) -> Optional[Type]:
29572957
if tp.type.fullname() in ['builtins.list', 'builtins.tuple', 'builtins.dict',
29582958
'builtins.set', 'builtins.frozenset']:
29592959
if not tp.args:
2960-
# TODO: make lib-stub/builtins.pyi define generic tuple.
2960+
# TODO: fix tuple in lib-stub/builtins.pyi (it should be generic).
29612961
return None
29622962
if not isinstance(tp.args[0], AnyType):
29632963
return tp.args[0]
29642964
elif isinstance(tp, TupleType) and all(not isinstance(it, AnyType) for it in tp.items):
2965-
return join_type_list(tp.items)
2965+
return UnionType.make_simplified_union(tp.items) # this type is not externally visible
29662966
elif isinstance(tp, TypedDictType):
29672967
# TypedDict always has non-optional string keys.
29682968
if tp.fallback.type.fullname() == 'typing.Mapping':
@@ -3084,15 +3084,6 @@ def find_isinstance_check(node: Expression,
30843084
if literal(expr) == LITERAL_TYPE:
30853085
vartype = type_map[expr]
30863086
return conditional_callable_type_map(expr, vartype)
3087-
elif isinstance(node, ComparisonExpr) and node.operators in [['in'], ['not in']]:
3088-
expr = node.operands[0]
3089-
cont_type = type_map[node.operands[1]]
3090-
item_type = builtin_item_type(cont_type)
3091-
if item_type and literal(expr) == LITERAL_TYPE and not is_literal_none(expr):
3092-
if node.operators == ['in']:
3093-
return {expr: item_type}, {}
3094-
if node.operators == ['not in']:
3095-
return {}, {expr: item_type}
30963087
elif isinstance(node, ComparisonExpr) and experiments.STRICT_OPTIONAL:
30973088
# Check for `x is None` and `x is not None`.
30983089
is_not = node.operators == ['is not']
@@ -3127,6 +3118,20 @@ def find_isinstance_check(node: Expression,
31273118
optional_expr = node.operands[1]
31283119
if is_overlapping_types(optional_type, comp_type):
31293120
return {optional_expr: remove_optional(optional_type)}, {}
3121+
elif node.operators in [['in'], ['not in']]:
3122+
expr = node.operands[0]
3123+
left_type = type_map[expr]
3124+
right_type = builtin_item_type(type_map[node.operands[1]])
3125+
right_ok = right_type and (not is_optional(right_type) and
3126+
(not isinstance(right_type, Instance) or
3127+
right_type.type.fullname() != 'builtins.object'))
3128+
if (right_type and right_ok and is_optional(left_type) and
3129+
literal(expr) == LITERAL_TYPE and not is_literal_none(expr) and
3130+
is_overlapping_types(left_type, right_type)):
3131+
if node.operators == ['in']:
3132+
return {expr: remove_optional(left_type)}, {}
3133+
if node.operators == ['not in']:
3134+
return {}, {expr: remove_optional(left_type)}
31303135
elif isinstance(node, RefExpr):
31313136
# Restrict the type of the variable to True-ish/False-ish in the if and else branches
31323137
# respectively

mypy/semanal_pass3.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ def visit_decorator(self, dec: Decorator) -> None:
152152
for expr in dec.decorators:
153153
preserve_type = False
154154
if isinstance(expr, RefExpr) and isinstance(expr.node, FuncDef):
155-
if is_identity_signature(expr.node.type):
155+
if expr.node.type and is_identity_signature(expr.node.type):
156156
preserve_type = True
157157
if not preserve_type:
158158
decorator_preserves_type = False
@@ -246,31 +246,38 @@ def perform_transform(self, node: Union[Node, SymbolTableNode],
246246
transform: Callable[[Type], Type]) -> None:
247247
"""Apply transform to all types associated with node."""
248248
if isinstance(node, ForStmt):
249-
node.index_type = transform(node.index_type)
249+
if node.index_type:
250+
node.index_type = transform(node.index_type)
250251
self.transform_types_in_lvalue(node.index, transform)
251252
if isinstance(node, WithStmt):
252-
node.target_type = transform(node.target_type)
253+
if node.target_type:
254+
node.target_type = transform(node.target_type)
253255
for n in node.target:
254256
if isinstance(n, NameExpr) and isinstance(n.node, Var) and n.node.type:
255257
n.node.type = transform(n.node.type)
256258
if isinstance(node, (FuncDef, CastExpr, AssignmentStmt, TypeAliasExpr, Var)):
259+
assert node.type, "Scheduled patch for non-existent type"
257260
node.type = transform(node.type)
258261
if isinstance(node, NewTypeExpr):
262+
assert node.old_type, "Scheduled patch for non-existent type"
259263
node.old_type = transform(node.old_type)
260264
if isinstance(node, TypeVarExpr):
261265
if node.upper_bound:
262266
node.upper_bound = transform(node.upper_bound)
263267
if node.values:
264268
node.values = [transform(v) for v in node.values]
265269
if isinstance(node, TypedDictExpr):
270+
assert node.info.typeddict_type, "Scheduled patch for non-existent type"
266271
node.info.typeddict_type = cast(TypedDictType,
267272
transform(node.info.typeddict_type))
268273
if isinstance(node, NamedTupleExpr):
274+
assert node.info.tuple_type, "Scheduled patch for non-existent type"
269275
node.info.tuple_type = cast(TupleType,
270276
transform(node.info.tuple_type))
271277
if isinstance(node, TypeApplication):
272278
node.types = [transform(t) for t in node.types]
273279
if isinstance(node, SymbolTableNode):
280+
assert node.type_override, "Scheduled patch for non-existent type"
274281
node.type_override = transform(node.type_override)
275282
if isinstance(node, TypeInfo):
276283
for tvar in node.defn.type_vars:
@@ -296,7 +303,8 @@ def transform_types_in_lvalue(self, lvalue: Lvalue,
296303
if isinstance(lvalue, RefExpr):
297304
if isinstance(lvalue.node, Var):
298305
var = lvalue.node
299-
var.type = transform(var.type)
306+
if var.type:
307+
var.type = transform(var.type)
300308
elif isinstance(lvalue, TupleExpr):
301309
for item in lvalue.items:
302310
self.transform_types_in_lvalue(item, transform)
@@ -355,7 +363,7 @@ def fail(self, msg: str, ctx: Context, *, blocker: bool = False) -> None:
355363
def fail_blocker(self, msg: str, ctx: Context) -> None:
356364
self.fail(msg, ctx, blocker=True)
357365

358-
def builtin_type(self, name: str, args: List[Type] = None) -> Instance:
366+
def builtin_type(self, name: str, args: Optional[List[Type]] = None) -> Instance:
359367
names = self.modules['builtins']
360368
sym = names.names[name]
361369
node = sym.node

0 commit comments

Comments
 (0)