@@ -1531,55 +1531,68 @@ def check_generator_or_comprehension(self, gen: GeneratorExpr,
1531
1531
type_name : str ,
1532
1532
id_for_messages : str ) -> Type :
1533
1533
"""Type check a generator expression or a list comprehension."""
1534
- self .check_for_comp (gen )
1534
+ with self .chk .binder .frame_context ():
1535
+ self .check_for_comp (gen )
1535
1536
1536
- # Infer the type of the list comprehension by using a synthetic generic
1537
- # callable type.
1538
- tvdef = TypeVarDef ('T' , - 1 , [], self .chk .object_type ())
1539
- tv = TypeVarType (tvdef )
1540
- constructor = CallableType (
1541
- [tv ],
1542
- [nodes .ARG_POS ],
1543
- [None ],
1544
- self .chk .named_generic_type (type_name , [tv ]),
1545
- self .chk .named_type ('builtins.function' ),
1546
- name = id_for_messages ,
1547
- variables = [tvdef ])
1548
- return self .check_call (constructor ,
1549
- [gen .left_expr ], [nodes .ARG_POS ], gen )[0 ]
1537
+ # Infer the type of the list comprehension by using a synthetic generic
1538
+ # callable type.
1539
+ tvdef = TypeVarDef ('T' , - 1 , [], self .chk .object_type ())
1540
+ tv = TypeVarType (tvdef )
1541
+ constructor = CallableType (
1542
+ [tv ],
1543
+ [nodes .ARG_POS ],
1544
+ [None ],
1545
+ self .chk .named_generic_type (type_name , [tv ]),
1546
+ self .chk .named_type ('builtins.function' ),
1547
+ name = id_for_messages ,
1548
+ variables = [tvdef ])
1549
+ return self .check_call (constructor ,
1550
+ [gen .left_expr ], [nodes .ARG_POS ], gen )[0 ]
1550
1551
1551
1552
def visit_dictionary_comprehension (self , e : DictionaryComprehension ) -> Type :
1552
1553
"""Type check a dictionary comprehension."""
1553
- self .check_for_comp (e )
1554
-
1555
- # Infer the type of the list comprehension by using a synthetic generic
1556
- # callable type.
1557
- ktdef = TypeVarDef ('KT' , - 1 , [], self .chk .object_type ())
1558
- vtdef = TypeVarDef ('VT' , - 2 , [], self .chk .object_type ())
1559
- kt = TypeVarType (ktdef )
1560
- vt = TypeVarType (vtdef )
1561
- constructor = CallableType (
1562
- [kt , vt ],
1563
- [nodes .ARG_POS , nodes .ARG_POS ],
1564
- [None , None ],
1565
- self .chk .named_generic_type ('builtins.dict' , [kt , vt ]),
1566
- self .chk .named_type ('builtins.function' ),
1567
- name = '<dictionary-comprehension>' ,
1568
- variables = [ktdef , vtdef ])
1569
- return self .check_call (constructor ,
1570
- [e .key , e .value ], [nodes .ARG_POS , nodes .ARG_POS ], e )[0 ]
1554
+ with self .chk .binder .frame_context ():
1555
+ self .check_for_comp (e )
1556
+
1557
+ # Infer the type of the list comprehension by using a synthetic generic
1558
+ # callable type.
1559
+ ktdef = TypeVarDef ('KT' , - 1 , [], self .chk .object_type ())
1560
+ vtdef = TypeVarDef ('VT' , - 2 , [], self .chk .object_type ())
1561
+ kt = TypeVarType (ktdef )
1562
+ vt = TypeVarType (vtdef )
1563
+ constructor = CallableType (
1564
+ [kt , vt ],
1565
+ [nodes .ARG_POS , nodes .ARG_POS ],
1566
+ [None , None ],
1567
+ self .chk .named_generic_type ('builtins.dict' , [kt , vt ]),
1568
+ self .chk .named_type ('builtins.function' ),
1569
+ name = '<dictionary-comprehension>' ,
1570
+ variables = [ktdef , vtdef ])
1571
+ return self .check_call (constructor ,
1572
+ [e .key , e .value ], [nodes .ARG_POS , nodes .ARG_POS ], e )[0 ]
1571
1573
1572
1574
def check_for_comp (self , e : Union [GeneratorExpr , DictionaryComprehension ]) -> None :
1573
1575
"""Check the for_comp part of comprehensions. That is the part from 'for':
1574
1576
... for x in y if z
1577
+
1578
+ Note: This adds the type information derived from the condlists to the current binder.
1575
1579
"""
1576
- with self .chk .binder .frame_context ():
1577
- for index , sequence , conditions in zip (e .indices , e .sequences ,
1578
- e .condlists ):
1579
- sequence_type = self .chk .analyze_iterable_item_type (sequence )
1580
- self .chk .analyze_index_variables (index , sequence_type , e )
1581
- for condition in conditions :
1582
- self .accept (condition )
1580
+ for index , sequence , conditions in zip (e .indices , e .sequences ,
1581
+ e .condlists ):
1582
+ sequence_type = self .chk .analyze_iterable_item_type (sequence )
1583
+ self .chk .analyze_index_variables (index , sequence_type , e )
1584
+ for condition in conditions :
1585
+ self .accept (condition )
1586
+
1587
+ # values are only part of the comprehension when all conditions are true
1588
+ true_map , _ = mypy .checker .find_isinstance_check (
1589
+ condition , self .chk .type_map ,
1590
+ self .chk .typing_mode_weak ()
1591
+ )
1592
+
1593
+ if true_map :
1594
+ for var , type in true_map .items ():
1595
+ self .chk .binder .push (var , type )
1583
1596
1584
1597
def visit_conditional_expr (self , e : ConditionalExpr ) -> Type :
1585
1598
cond_type = self .accept (e .cond )
0 commit comments