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