@@ -147,6 +147,18 @@ def redefines(self, other):
147
147
return isinstance (other , Definition ) and self .name == other .name
148
148
149
149
150
+ class FutureImportation (Importation ):
151
+ """
152
+ A binding created by a from `__future__` import statement.
153
+
154
+ `__future__` imports are implicitly used.
155
+ """
156
+
157
+ def __init__ (self , name , source , scope ):
158
+ super (FutureImportation , self ).__init__ (name , source )
159
+ self .used = (scope , source )
160
+
161
+
150
162
class Argument (Binding ):
151
163
"""
152
164
Represents binding a name as an argument.
@@ -244,6 +256,7 @@ class GeneratorScope(Scope):
244
256
245
257
class ModuleScope (Scope ):
246
258
"""Scope for a module."""
259
+ _futures_allowed = True
247
260
248
261
249
262
class DoctestScope (ModuleScope ):
@@ -299,7 +312,6 @@ def __init__(self, tree, filename='(none)', builtins=None,
299
312
self .withDoctest = withDoctest
300
313
self .scopeStack = [ModuleScope ()]
301
314
self .exceptHandlers = [()]
302
- self .futuresAllowed = True
303
315
self .root = tree
304
316
self .handleChildren (tree )
305
317
self .runDeferred (self ._deferredFunctions )
@@ -314,6 +326,28 @@ def __init__(self, tree, filename='(none)', builtins=None,
314
326
self .popScope ()
315
327
self .checkDeadScopes ()
316
328
329
+ @property
330
+ def futuresAllowed (self ):
331
+ if len (self .scopeStack ) > 2 :
332
+ return False
333
+
334
+ if not all (isinstance (scope , ModuleScope )
335
+ for scope in self .scopeStack ):
336
+ return False
337
+
338
+ if not self .scope ._futures_allowed :
339
+ return False
340
+
341
+ return all (isinstance (binding , FutureImportation )
342
+ for binding in self .scope .values ())
343
+
344
+ @futuresAllowed .setter
345
+ def futuresAllowed (self , value ):
346
+ assert value == False
347
+ if not isinstance (self .scope , ModuleScope ):
348
+ return
349
+ self .scope ._futures_allowed = False
350
+
317
351
def deferFunction (self , callable ):
318
352
"""
319
353
Schedule a function handler to be called just before completion.
@@ -975,7 +1009,10 @@ def IMPORTFROM(self, node):
975
1009
self .futuresAllowed = False
976
1010
977
1011
for alias in node .names :
978
- if alias .name == '*' :
1012
+ name = alias .asname or alias .name
1013
+ if node .module == '__future__' :
1014
+ importation = FutureImportation (name , node , self .scope )
1015
+ elif alias .name == '*' :
979
1016
# Only Python 2, local import * is a SyntaxWarning
980
1017
if not PY2 and not isinstance (self .scope , ModuleScope ):
981
1018
self .report (messages .ImportStarNotPermitted ,
@@ -984,10 +1021,8 @@ def IMPORTFROM(self, node):
984
1021
self .scope .importStarred = True
985
1022
self .report (messages .ImportStarUsed , node , node .module )
986
1023
continue
987
- name = alias .asname or alias .name
988
- importation = Importation (name , node )
989
- if node .module == '__future__' :
990
- importation .used = (self .scope , node )
1024
+ else :
1025
+ importation = Importation (name , node )
991
1026
self .addBinding (node , importation )
992
1027
993
1028
def TRY (self , node ):
0 commit comments