@@ -68,7 +68,25 @@ class Key(AnyType):
68
68
69
69
70
70
class ConditionalTypeBinder :
71
- """Keep track of conditional types of variables."""
71
+ """Keep track of conditional types of variables.
72
+
73
+ NB: Variables are tracked by literal expression, so it is possible
74
+ to confuse the binder; for example,
75
+
76
+ ```
77
+ class A:
78
+ a = None # type: Union[int, str]
79
+ x = A()
80
+ lst = [x]
81
+ reveal_type(x.a) # Union[int, str]
82
+ x.a = 1
83
+ reveal_type(x.a) # int
84
+ reveal_type(lst[0].a) # Union[int, str]
85
+ lst[0].a = 'a'
86
+ reveal_type(x.a) # int
87
+ reveal_type(lst[0].a) # str
88
+ ```
89
+ """
72
90
73
91
def __init__ (self ) -> None :
74
92
# The set of frames currently used. These map
@@ -87,10 +105,13 @@ def __init__(self) -> None:
87
105
# Whenever a new key (e.g. x.a.b) is added, we update this
88
106
self .dependencies = {} # type: Dict[Key, Set[Key]]
89
107
90
- # Set to True on return/break/raise, False on blocks that can block any of them
108
+ # breaking_out is set to True on return/break/continue/raise
109
+ # It is cleared on pop_frame() and placed in last_pop_breaking_out
110
+ # Lines of code after breaking_out = True are unreachable and not
111
+ # typechecked.
91
112
self .breaking_out = False
92
113
93
- # Whether the last pop changed the top frame on exit
114
+ # Whether the last pop changed the newly top frame on exit
94
115
self .last_pop_changed = False
95
116
# Whether the last pop was necessarily breaking out, and couldn't fall through
96
117
self .last_pop_breaking_out = False
0 commit comments