@@ -409,7 +409,6 @@ class FunctionScope(Scope):
409409
410410 @ivar globals: Names declared 'global' in this function.
411411 """
412- usesLocals = False
413412 alwaysUsed = {'__tracebackhide__' , '__traceback_info__' ,
414413 '__traceback_supplement__' }
415414
@@ -426,7 +425,6 @@ def unusedAssignments(self):
426425 """
427426 for name , binding in self .items ():
428427 if (not binding .used and name not in self .globals
429- and not self .usesLocals
430428 and isinstance (binding , Assignment )):
431429 yield name , binding
432430
@@ -708,6 +706,16 @@ def handleNodeLoad(self, node):
708706 in_generators = None
709707 importStarred = None
710708
709+ if node .id == 'locals' and isinstance (node .parent , ast .Call ):
710+ # we are doing locals() call, which marks names currently
711+ # in scope as used.
712+ scope = self .scope
713+ if isinstance (scope , GeneratorScope ):
714+ scope = self .scopeStack [- 2 ]
715+ if isinstance (scope , FunctionScope ):
716+ for binding in scope .values ():
717+ binding .used = (self .scope , node )
718+
711719 # try enclosing function scopes and global scope
712720 for scope in self .scopeStack [- 1 ::- 1 ]:
713721 if isinstance (scope , ClassScope ):
@@ -1094,10 +1102,6 @@ def NAME(self, node):
10941102 # Locate the name in locals / function / globals scopes.
10951103 if isinstance (node .ctx , (ast .Load , ast .AugLoad )):
10961104 self .handleNodeLoad (node )
1097- if (node .id == 'locals' and isinstance (self .scope , FunctionScope )
1098- and isinstance (node .parent , ast .Call )):
1099- # we are doing locals() call in current scope
1100- self .scope .usesLocals = True
11011105 elif isinstance (node .ctx , (ast .Store , ast .AugStore )):
11021106 self .handleNodeStore (node )
11031107 elif isinstance (node .ctx , ast .Del ):
0 commit comments