@@ -262,10 +262,11 @@ class Binding:
262262 the node that this binding was last used.
263263 """
264264
265- def __init__ (self , name , source ):
265+ def __init__ (self , name , source , * , assigned = True ):
266266 self .name = name
267267 self .source = source
268268 self .used = False
269+ self .assigned = assigned
269270
270271 def __str__ (self ):
271272 return self .name
@@ -1073,6 +1074,12 @@ def addBinding(self, node, value):
10731074 break
10741075 existing = scope .get (value .name )
10751076
1077+ global_scope = self .scopeStack [- 1 ]
1078+ if (existing and global_scope .get (value .name ) == existing and
1079+ not existing .assigned ):
1080+ # make sure the variable is in the global scope before setting as assigned
1081+ existing .assigned = True
1082+
10761083 if (existing and not isinstance (existing , Builtin ) and
10771084 not self .differentForks (node , existing .source )):
10781085
@@ -1155,6 +1162,10 @@ def handleNodeLoad(self, node):
11551162 continue
11561163
11571164 binding = scope .get (name , None )
1165+
1166+ if getattr (binding , 'assigned' , None ) is False :
1167+ self .report (messages .UndefinedName , node , name )
1168+
11581169 if isinstance (binding , Annotation ) and not self ._in_postponed_annotation :
11591170 continue
11601171
@@ -1224,12 +1235,19 @@ def handleNodeStore(self, node):
12241235 continue
12251236 # if the name was defined in that scope, and the name has
12261237 # been accessed already in the current scope, and hasn't
1227- # been declared global
1238+ # been assigned globally
12281239 used = name in scope and scope [name ].used
12291240 if used and used [0 ] is self .scope and name not in self .scope .globals :
12301241 # then it's probably a mistake
12311242 self .report (messages .UndefinedLocal ,
12321243 scope [name ].used [1 ], name , scope [name ].source )
1244+
1245+ # and remove UndefinedName messages already reported for this name
1246+ self .messages = [
1247+ m for m in self .messages if not
1248+ isinstance (m , messages .UndefinedName ) or
1249+ m .message_args [0 ] != name ]
1250+
12331251 break
12341252
12351253 parent_stmt = self .getParent (node )
@@ -1933,11 +1951,9 @@ def GLOBAL(self, node):
19331951
19341952 # One 'global' statement can bind multiple (comma-delimited) names.
19351953 for node_name in node .names :
1936- node_value = Assignment (node_name , node )
1954+ node_value = Assignment (node_name , node , assigned = False )
19371955
19381956 # Remove UndefinedName messages already reported for this name.
1939- # TODO: if the global is not used in this scope, it does not
1940- # become a globally defined name. See test_unused_global.
19411957 self .messages = [
19421958 m for m in self .messages if not
19431959 isinstance (m , messages .UndefinedName ) or
0 commit comments