@@ -9,15 +9,25 @@ def __init__(self):
99 self .scopes = []
1010 # Add the global scope to the stack.
1111 self ._push_scope ()
12+ # Scope information specific to exception handlers.
13+ self .exception_handler_scopes = []
1214
1315 def _push_scope (self , is_comprehension = False ):
1416 self .scopes .append ({"defs" : set (), "is_comprehension" : is_comprehension })
1517
1618 def _pop_scope (self ):
1719 self .scopes .pop ()
1820
21+ def _push_exception_handler_scope (self ):
22+ self .exception_handler_scopes .append ({"defs" : set ()})
23+
24+ def _pop_exception_handler_scope (self ):
25+ self .exception_handler_scopes .pop ()
26+
1927 def _handle_ref (self , name ):
20- is_defined = any (name in scope ["defs" ] for scope in self .scopes )
28+ is_defined = any (name in scope ["defs" ] for scope in self .scopes ) or any (
29+ name in scope ["defs" ] for scope in self .exception_handler_scopes
30+ )
2131
2232 if not is_defined :
2333 self .refs .add (name )
@@ -164,6 +174,15 @@ def visit_AnnAssign(self, node):
164174
165175 self .visit (node .target )
166176
177+ def visit_ExceptHandler (self , node ):
178+ # Exception handlers define local variables available only within
179+ # the handler, however the handler body is still within the outer
180+ # scope, so we add a special ref-only scope.
181+ self ._push_exception_handler_scope ()
182+ self .exception_handler_scopes [- 1 ]["defs" ].add (node .name )
183+ self .generic_visit (node )
184+ self ._pop_exception_handler_scope ()
185+
167186 def visit_MatchAs (self , node ):
168187 if node .name is not None :
169188 self .scopes [- 1 ]["defs" ].add (node .name )
0 commit comments