@@ -322,10 +322,11 @@ class Binding(object):
322
322
the node that this binding was last used.
323
323
"""
324
324
325
- def __init__ (self , name , source ):
325
+ def __init__ (self , name , source , * , assigned = True ):
326
326
self .name = name
327
327
self .source = source
328
328
self .used = False
329
+ self .assigned = assigned
329
330
330
331
def __str__ (self ):
331
332
return self .name
@@ -1129,6 +1130,12 @@ def addBinding(self, node, value):
1129
1130
break
1130
1131
existing = scope .get (value .name )
1131
1132
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
+
1132
1139
if (existing and not isinstance (existing , Builtin ) and
1133
1140
not self .differentForks (node , existing .source )):
1134
1141
@@ -1207,6 +1214,10 @@ def handleNodeLoad(self, node):
1207
1214
continue
1208
1215
1209
1216
binding = scope .get (name , None )
1217
+
1218
+ if getattr (binding , 'assigned' , None ) is False :
1219
+ self .report (messages .UndefinedName , node , name )
1220
+
1210
1221
if isinstance (binding , Annotation ) and not self ._in_postponed_annotation :
1211
1222
continue
1212
1223
@@ -1276,12 +1287,19 @@ def handleNodeStore(self, node):
1276
1287
continue
1277
1288
# if the name was defined in that scope, and the name has
1278
1289
# been accessed already in the current scope, and hasn't
1279
- # been declared global
1290
+ # been assigned globally
1280
1291
used = name in scope and scope [name ].used
1281
1292
if used and used [0 ] is self .scope and name not in self .scope .globals :
1282
1293
# then it's probably a mistake
1283
1294
self .report (messages .UndefinedLocal ,
1284
1295
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
+
1285
1303
break
1286
1304
1287
1305
parent_stmt = self .getParent (node )
@@ -2002,11 +2020,9 @@ def GLOBAL(self, node):
2002
2020
2003
2021
# One 'global' statement can bind multiple (comma-delimited) names.
2004
2022
for node_name in node .names :
2005
- node_value = Assignment (node_name , node )
2023
+ node_value = Assignment (node_name , node , assigned = False )
2006
2024
2007
2025
# 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.
2010
2026
self .messages = [
2011
2027
m for m in self .messages if not
2012
2028
isinstance (m , messages .UndefinedName ) or
0 commit comments