@@ -147,6 +147,18 @@ def redefines(self, other):
147147 return isinstance (other , Definition ) and self .name == other .name
148148
149149
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+
150162class Argument (Binding ):
151163 """
152164 Represents binding a name as an argument.
@@ -244,6 +256,7 @@ class GeneratorScope(Scope):
244256
245257class ModuleScope (Scope ):
246258 """Scope for a module."""
259+ _futures_allowed = True
247260
248261
249262class DoctestScope (ModuleScope ):
@@ -299,7 +312,6 @@ def __init__(self, tree, filename='(none)', builtins=None,
299312 self .withDoctest = withDoctest
300313 self .scopeStack = [ModuleScope ()]
301314 self .exceptHandlers = [()]
302- self .futuresAllowed = True
303315 self .root = tree
304316 self .handleChildren (tree )
305317 self .runDeferred (self ._deferredFunctions )
@@ -314,6 +326,28 @@ def __init__(self, tree, filename='(none)', builtins=None,
314326 self .popScope ()
315327 self .checkDeadScopes ()
316328
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 is False
347+ if not isinstance (self .scope , ModuleScope ):
348+ return
349+ self .scope ._futures_allowed = False
350+
317351 def deferFunction (self , callable ):
318352 """
319353 Schedule a function handler to be called just before completion.
@@ -975,7 +1009,10 @@ def IMPORTFROM(self, node):
9751009 self .futuresAllowed = False
9761010
9771011 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 == '*' :
9791016 # Only Python 2, local import * is a SyntaxWarning
9801017 if not PY2 and not isinstance (self .scope , ModuleScope ):
9811018 self .report (messages .ImportStarNotPermitted ,
@@ -984,10 +1021,8 @@ def IMPORTFROM(self, node):
9841021 self .scope .importStarred = True
9851022 self .report (messages .ImportStarUsed , node , node .module )
9861023 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 )
9911026 self .addBinding (node , importation )
9921027
9931028 def TRY (self , node ):
0 commit comments