Skip to content

Commit 33bbb82

Browse files
authored
pushScope / popScope -> with in_scope(...) (#755)
1 parent c3273c5 commit 33bbb82

File tree

1 file changed

+45
-47
lines changed

1 file changed

+45
-47
lines changed

pyflakes/checker.py

Lines changed: 45 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -753,19 +753,21 @@ def __init__(self, tree, filename='(none)', builtins=None,
753753
if builtins:
754754
self.builtIns = self.builtIns.union(builtins)
755755
self.withDoctest = withDoctest
756+
self.exceptHandlers = [()]
757+
self.root = tree
758+
759+
self.scopeStack = []
756760
try:
757-
self.scopeStack = [Checker._ast_node_scope[type(tree)]()]
761+
scope_tp = Checker._ast_node_scope[type(tree)]
758762
except KeyError:
759763
raise RuntimeError('No scope implemented for the node %r' % tree)
760-
self.exceptHandlers = [()]
761-
self.root = tree
762-
for builtin in self.builtIns:
763-
self.addBinding(None, Builtin(builtin))
764-
self.handleChildren(tree)
765764

766-
self._run_deferred()
765+
with self.in_scope(scope_tp):
766+
for builtin in self.builtIns:
767+
self.addBinding(None, Builtin(builtin))
768+
self.handleChildren(tree)
769+
self._run_deferred()
767770

768-
self.popScope()
769771
self.checkDeadScopes()
770772

771773
if file_tokens:
@@ -830,8 +832,13 @@ def annotationsFutureEnabled(self, value):
830832
def scope(self):
831833
return self.scopeStack[-1]
832834

833-
def popScope(self):
834-
self.deadScopes.append(self.scopeStack.pop())
835+
@contextlib.contextmanager
836+
def in_scope(self, cls):
837+
self.scopeStack.append(cls())
838+
try:
839+
yield
840+
finally:
841+
self.deadScopes.append(self.scopeStack.pop())
835842

836843
def checkDeadScopes(self):
837844
"""
@@ -899,9 +906,6 @@ def checkDeadScopes(self):
899906
messg = messages.RedefinedWhileUnused
900907
self.report(messg, node, value.name, value.source)
901908

902-
def pushScope(self, scopeClass=FunctionScope):
903-
self.scopeStack.append(scopeClass())
904-
905909
def report(self, messageClass, *args, **kwargs):
906910
self.messages.append(messageClass(self.filename, *args, **kwargs))
907911

@@ -1264,22 +1268,21 @@ def handleDoctests(self, node):
12641268
saved_stack = self.scopeStack
12651269
self.scopeStack = [self.scopeStack[0]]
12661270
node_offset = self.offset or (0, 0)
1267-
self.pushScope(DoctestScope)
1268-
if '_' not in self.scopeStack[0]:
1269-
self.addBinding(None, Builtin('_'))
1270-
for example in examples:
1271-
try:
1272-
tree = ast.parse(example.source, "<doctest>")
1273-
except SyntaxError as e:
1274-
position = (node_lineno + example.lineno + e.lineno,
1275-
example.indent + 4 + (e.offset or 0))
1276-
self.report(messages.DoctestSyntaxError, node, position)
1277-
else:
1278-
self.offset = (node_offset[0] + node_lineno + example.lineno,
1279-
node_offset[1] + example.indent + 4)
1280-
self.handleChildren(tree)
1281-
self.offset = node_offset
1282-
self.popScope()
1271+
with self.in_scope(DoctestScope):
1272+
if '_' not in self.scopeStack[0]:
1273+
self.addBinding(None, Builtin('_'))
1274+
for example in examples:
1275+
try:
1276+
tree = ast.parse(example.source, "<doctest>")
1277+
except SyntaxError as e:
1278+
position = (node_lineno + example.lineno + e.lineno,
1279+
example.indent + 4 + (e.offset or 0))
1280+
self.report(messages.DoctestSyntaxError, node, position)
1281+
else:
1282+
self.offset = (node_offset[0] + node_lineno + example.lineno,
1283+
node_offset[1] + example.indent + 4)
1284+
self.handleChildren(tree)
1285+
self.offset = node_offset
12831286
self.scopeStack = saved_stack
12841287

12851288
@in_string_annotation
@@ -1825,9 +1828,8 @@ def GLOBAL(self, node):
18251828
NONLOCAL = GLOBAL
18261829

18271830
def GENERATOREXP(self, node):
1828-
self.pushScope(GeneratorScope)
1829-
self.handleChildren(node)
1830-
self.popScope()
1831+
with self.in_scope(GeneratorScope):
1832+
self.handleChildren(node)
18311833

18321834
LISTCOMP = DICTCOMP = SETCOMP = GENERATOREXP
18331835

@@ -1943,11 +1945,8 @@ def LAMBDA(self, node):
19431945
self.handleNode(default, node)
19441946

19451947
def runFunction():
1946-
self.pushScope()
1947-
1948-
self.handleChildren(node, omit=['decorator_list', 'returns'])
1949-
1950-
self.popScope()
1948+
with self.in_scope(FunctionScope):
1949+
self.handleChildren(node, omit=['decorator_list', 'returns'])
19511950

19521951
self.deferFunction(runFunction)
19531952

@@ -1969,16 +1968,15 @@ def CLASSDEF(self, node):
19691968
self.handleNode(baseNode, node)
19701969
for keywordNode in node.keywords:
19711970
self.handleNode(keywordNode, node)
1972-
self.pushScope(ClassScope)
1973-
# doctest does not process doctest within a doctest
1974-
# classes within classes are processed.
1975-
if (self.withDoctest and
1976-
not self._in_doctest() and
1977-
not isinstance(self.scope, FunctionScope)):
1978-
self.deferFunction(lambda: self.handleDoctests(node))
1979-
for stmt in node.body:
1980-
self.handleNode(stmt, node)
1981-
self.popScope()
1971+
with self.in_scope(ClassScope):
1972+
# doctest does not process doctest within a doctest
1973+
# classes within classes are processed.
1974+
if (self.withDoctest and
1975+
not self._in_doctest() and
1976+
not isinstance(self.scope, FunctionScope)):
1977+
self.deferFunction(lambda: self.handleDoctests(node))
1978+
for stmt in node.body:
1979+
self.handleNode(stmt, node)
19821980
self.addBinding(node, ClassDefinition(node.name, node))
19831981

19841982
def AUGASSIGN(self, node):

0 commit comments

Comments
 (0)