Skip to content

Commit a4447fc

Browse files
committed
[2/2] Support isinstance in conditional-if
We simply check for isinstance when visiting conditionals and correctly push for the if/else expressions, giving them new types only for those particular expressions. After that, the type of the variable being modified returns to its original type.
1 parent 6712919 commit a4447fc

File tree

2 files changed

+32
-2
lines changed

2 files changed

+32
-2
lines changed

mypy/checkexpr.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1275,8 +1275,25 @@ def check_for_comp(self, e: Union[GeneratorExpr, DictionaryComprehension]) -> No
12751275
def visit_conditional_expr(self, e: ConditionalExpr) -> Type:
12761276
cond_type = self.accept(e.cond)
12771277
self.check_not_void(cond_type, e)
1278-
if_type = self.accept(e.if_expr)
1279-
else_type = self.accept(e.else_expr, context=if_type)
1278+
1279+
# Gain type information from isinstance if it is there
1280+
# but only for the current expression
1281+
variable, inst_if_type, inst_else_type, kind = mypy.checker.find_isinstance_check(
1282+
e.cond,
1283+
self.chk.type_map,
1284+
self.chk.typing_mode_weak())
1285+
if variable:
1286+
self.chk.binder.push_frame()
1287+
self.chk.binder.push(variable, inst_if_type)
1288+
if_type = self.accept(e.if_expr)
1289+
self.chk.binder.pop_frame()
1290+
self.chk.binder.push_frame()
1291+
self.chk.binder.push(variable, inst_else_type)
1292+
else_type = self.accept(e.else_expr, context=if_type)
1293+
self.chk.binder.pop_frame()
1294+
else:
1295+
if_type = self.accept(e.if_expr)
1296+
else_type = self.accept(e.else_expr, context=if_type)
12801297
return join.join_types(if_type, else_type)
12811298

12821299
#

mypy/test/data/check-isinstance.test

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -708,3 +708,16 @@ x = B() # type: A
708708
if isinstance(x, B) and x.flag:
709709
pass
710710
[builtins fixtures/isinstancelist.py]
711+
[case testIsinstanceExpression]
712+
class A:
713+
pass
714+
715+
class B(A):
716+
flag = 1
717+
718+
x = B() # type: A
719+
720+
x.flag if isinstance(x, B) else 0
721+
0 if not isinstance(x, B) else x.flag
722+
0 if isinstance(x, B) else x.flag # E: "A" has no attribute "flag"
723+
[builtins fixtures/isinstancelist.py]

0 commit comments

Comments
 (0)