@@ -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 )
@@ -345,6 +357,20 @@ def _in_doctest(self):
345
357
return (len (self .scopeStack ) >= 2 and
346
358
isinstance (self .scopeStack [1 ], DoctestScope ))
347
359
360
+ @property
361
+ def futuresAllowed (self ):
362
+ if not all (isinstance (scope , ModuleScope )
363
+ for scope in self .scopeStack ):
364
+ return False
365
+
366
+ return self .scope ._futures_allowed
367
+
368
+ @futuresAllowed .setter
369
+ def futuresAllowed (self , value ):
370
+ assert value is False
371
+ if isinstance (self .scope , ModuleScope ):
372
+ self .scope ._futures_allowed = False
373
+
348
374
@property
349
375
def scope (self ):
350
376
return self .scopeStack [- 1 ]
@@ -974,7 +1000,10 @@ def IMPORTFROM(self, node):
974
1000
self .futuresAllowed = False
975
1001
976
1002
for alias in node .names :
977
- if alias .name == '*' :
1003
+ name = alias .asname or alias .name
1004
+ if node .module == '__future__' :
1005
+ importation = FutureImportation (name , node , self .scope )
1006
+ elif alias .name == '*' :
978
1007
# Only Python 2, local import * is a SyntaxWarning
979
1008
if not PY2 and not isinstance (self .scope , ModuleScope ):
980
1009
self .report (messages .ImportStarNotPermitted ,
@@ -983,10 +1012,8 @@ def IMPORTFROM(self, node):
983
1012
self .scope .importStarred = True
984
1013
self .report (messages .ImportStarUsed , node , node .module )
985
1014
continue
986
- name = alias .asname or alias .name
987
- importation = Importation (name , node )
988
- if node .module == '__future__' :
989
- importation .used = (self .scope , node )
1015
+ else :
1016
+ importation = Importation (name , node )
990
1017
self .addBinding (node , importation )
991
1018
992
1019
def TRY (self , node ):
0 commit comments