7
7
import __future__
8
8
import builtins
9
9
import ast
10
+ import collections
10
11
import contextlib
11
12
import doctest
12
13
import functools
@@ -735,7 +736,6 @@ class Checker:
735
736
nodeDepth = 0
736
737
offset = None
737
738
_in_annotation = AnnotationState .NONE
738
- _in_deferred = False
739
739
740
740
builtIns = set (builtin_vars ).union (_MAGIC_GLOBALS )
741
741
_customBuiltIns = os .environ .get ('PYFLAKES_BUILTINS' )
@@ -746,7 +746,7 @@ class Checker:
746
746
def __init__ (self , tree , filename = '(none)' , builtins = None ,
747
747
withDoctest = 'PYFLAKES_DOCTEST' in os .environ , file_tokens = ()):
748
748
self ._nodeHandlers = {}
749
- self ._deferredFunctions = []
749
+ self ._deferred = collections . deque ()
750
750
self .deadScopes = []
751
751
self .messages = []
752
752
self .filename = filename
@@ -762,12 +762,8 @@ def __init__(self, tree, filename='(none)', builtins=None,
762
762
for builtin in self .builtIns :
763
763
self .addBinding (None , Builtin (builtin ))
764
764
self .handleChildren (tree )
765
- self ._in_deferred = True
766
- self .runDeferred (self ._deferredFunctions )
767
- # Set _deferredFunctions to None so that deferFunction will fail
768
- # noisily if called after we've run through the deferred functions.
769
- self ._deferredFunctions = None
770
- del self .scopeStack [1 :]
765
+
766
+ self ._run_deferred ()
771
767
772
768
self .popScope ()
773
769
self .checkDeadScopes ()
@@ -787,17 +783,18 @@ def deferFunction(self, callable):
787
783
`callable` is called, the scope at the time this is called will be
788
784
restored, however it will contain any new bindings added to it.
789
785
"""
790
- self ._deferredFunctions .append ((callable , self .scopeStack [:], self .offset ))
786
+ self ._deferred .append ((callable , self .scopeStack [:], self .offset ))
791
787
792
- def runDeferred (self , deferred ):
793
- """
794
- Run the callables in C{deferred} using their associated scope stack.
795
- """
796
- for handler , scope , offset in deferred :
797
- self .scopeStack = scope
798
- self .offset = offset
788
+ def _run_deferred (self ):
789
+ orig = (self .scopeStack , self .offset )
790
+
791
+ while self ._deferred :
792
+ handler , scope , offset = self ._deferred .popleft ()
793
+ self .scopeStack , self .offset = scope , offset
799
794
handler ()
800
795
796
+ self .scopeStack , self .offset = orig
797
+
801
798
def _in_doctest (self ):
802
799
return (len (self .scopeStack ) >= 2 and
803
800
isinstance (self .scopeStack [1 ], DoctestScope ))
@@ -1696,10 +1693,7 @@ def STR(self, node):
1696
1693
node .col_offset ,
1697
1694
messages .ForwardAnnotationSyntaxError ,
1698
1695
)
1699
- if self ._in_deferred :
1700
- fn ()
1701
- else :
1702
- self .deferFunction (fn )
1696
+ self .deferFunction (fn )
1703
1697
1704
1698
def CONSTANT (self , node ):
1705
1699
if isinstance (node .value , str ):
0 commit comments