@@ -322,10 +322,11 @@ class Binding(object):
322322 the node that this binding was last used.
323323 """
324324
325- def __init__ (self , name , source ):
325+ def __init__ (self , name , source , * , assigned = True ):
326326 self .name = name
327327 self .source = source
328328 self .used = False
329+ self .assigned = assigned
329330
330331 def __str__ (self ):
331332 return self .name
@@ -1129,6 +1130,12 @@ def addBinding(self, node, value):
11291130 break
11301131 existing = scope .get (value .name )
11311132
1133+ global_scope = self .scopeStack [- 1 ]
1134+ if (existing and global_scope .get (value .name ) == existing and
1135+ not existing .assigned ):
1136+ # make sure the variable is in the global scope before setting as assigned
1137+ existing .assigned = True
1138+
11321139 if (existing and not isinstance (existing , Builtin ) and
11331140 not self .differentForks (node , existing .source )):
11341141
@@ -1207,6 +1214,10 @@ def handleNodeLoad(self, node):
12071214 continue
12081215
12091216 binding = scope .get (name , None )
1217+
1218+ if getattr (binding , 'assigned' , None ) is False :
1219+ self .report (messages .UndefinedName , node , name )
1220+
12101221 if isinstance (binding , Annotation ) and not self ._in_postponed_annotation :
12111222 continue
12121223
@@ -1276,12 +1287,19 @@ def handleNodeStore(self, node):
12761287 continue
12771288 # if the name was defined in that scope, and the name has
12781289 # been accessed already in the current scope, and hasn't
1279- # been declared global
1290+ # been assigned globally
12801291 used = name in scope and scope [name ].used
12811292 if used and used [0 ] is self .scope and name not in self .scope .globals :
12821293 # then it's probably a mistake
12831294 self .report (messages .UndefinedLocal ,
12841295 scope [name ].used [1 ], name , scope [name ].source )
1296+
1297+ # and we can remove UndefinedName messages already reported for this name
1298+ self .messages = [
1299+ m for m in self .messages if not
1300+ isinstance (m , messages .UndefinedName ) or
1301+ m .message_args [0 ] != name ]
1302+
12851303 break
12861304
12871305 parent_stmt = self .getParent (node )
@@ -2002,11 +2020,9 @@ def GLOBAL(self, node):
20022020
20032021 # One 'global' statement can bind multiple (comma-delimited) names.
20042022 for node_name in node .names :
2005- node_value = Assignment (node_name , node )
2023+ node_value = Assignment (node_name , node , assigned = False )
20062024
20072025 # Remove UndefinedName messages already reported for this name.
2008- # TODO: if the global is not used in this scope, it does not
2009- # become a globally defined name. See test_unused_global.
20102026 self .messages = [
20112027 m for m in self .messages if not
20122028 isinstance (m , messages .UndefinedName ) or
0 commit comments