diff options
author | Neil Schemenauer <nascheme@enme.ucalgary.ca> | 2006-08-16 23:38:05 (GMT) |
---|---|---|
committer | Neil Schemenauer <nascheme@enme.ucalgary.ca> | 2006-08-16 23:38:05 (GMT) |
commit | 4c6b0d5bec587770e0d83b550faae97fe251cc65 (patch) | |
tree | 1b472e824d748456dc4823ca047d67fd807c8d2f /Lib | |
parent | 7ae354846fff616746eeba6d27ccd5c175591cae (diff) | |
download | cpython-4c6b0d5bec587770e0d83b550faae97fe251cc65.zip cpython-4c6b0d5bec587770e0d83b550faae97fe251cc65.tar.gz cpython-4c6b0d5bec587770e0d83b550faae97fe251cc65.tar.bz2 |
Fix a bug in the ``compiler`` package that caused invalid code to be
generated for generator expressions.
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/compiler/ast.py | 4 | ||||
-rw-r--r-- | Lib/compiler/pycodegen.py | 19 | ||||
-rw-r--r-- | Lib/compiler/symbols.py | 2 | ||||
-rw-r--r-- | Lib/test/test_compiler.py | 7 |
4 files changed, 23 insertions, 9 deletions
diff --git a/Lib/compiler/ast.py b/Lib/compiler/ast.py index 8dcdf68..93437d6 100644 --- a/Lib/compiler/ast.py +++ b/Lib/compiler/ast.py @@ -583,11 +583,9 @@ class GenExpr(Node): def __init__(self, code, lineno=None): self.code = code self.lineno = lineno - self.argnames = ['[outmost-iterable]'] + self.argnames = ['.0'] self.varargs = self.kwargs = None - - def getChildren(self): return self.code, diff --git a/Lib/compiler/pycodegen.py b/Lib/compiler/pycodegen.py index e3667b5..009438d 100644 --- a/Lib/compiler/pycodegen.py +++ b/Lib/compiler/pycodegen.py @@ -658,18 +658,19 @@ class CodeGenerator: stack = [] for i, for_ in zip(range(len(node.quals)), node.quals): - start, anchor = self.visit(for_) + start, anchor, end = self.visit(for_) cont = None for if_ in for_.ifs: if cont is None: cont = self.newBlock() self.visit(if_, cont) - stack.insert(0, (start, cont, anchor)) + stack.insert(0, (start, cont, anchor, end)) self.visit(node.expr) self.emit('YIELD_VALUE') + self.emit('POP_TOP') - for start, cont, anchor in stack: + for start, cont, anchor, end in stack: if cont: skip_one = self.newBlock() self.emit('JUMP_FORWARD', skip_one) @@ -678,14 +679,22 @@ class CodeGenerator: self.nextBlock(skip_one) self.emit('JUMP_ABSOLUTE', start) self.startBlock(anchor) + self.emit('POP_BLOCK') + self.setups.pop() + self.startBlock(end) + self.emit('LOAD_CONST', None) def visitGenExprFor(self, node): start = self.newBlock() anchor = self.newBlock() + end = self.newBlock() + + self.setups.push((LOOP, start)) + self.emit('SETUP_LOOP', end) if node.is_outmost: - self.loadName('[outmost-iterable]') + self.loadName('.0') else: self.visit(node.iter) self.emit('GET_ITER') @@ -695,7 +704,7 @@ class CodeGenerator: self.emit('FOR_ITER', anchor) self.nextBlock() self.visit(node.assign) - return start, anchor + return start, anchor, end def visitGenExprIf(self, node, branch): self.set_lineno(node, force=True) diff --git a/Lib/compiler/symbols.py b/Lib/compiler/symbols.py index 8eb5fce..8f62980 100644 --- a/Lib/compiler/symbols.py +++ b/Lib/compiler/symbols.py @@ -188,7 +188,7 @@ class GenExprScope(Scope): i = self.__counter self.__counter += 1 self.__super_init("generator expression<%d>"%i, module, klass) - self.add_param('[outmost-iterable]') + self.add_param('.0') def get_names(self): keys = Scope.get_names(self) diff --git a/Lib/test/test_compiler.py b/Lib/test/test_compiler.py index 1efb6a6..81f2ea8 100644 --- a/Lib/test/test_compiler.py +++ b/Lib/test/test_compiler.py @@ -116,6 +116,13 @@ class CompilerTest(unittest.TestCase): exec c in dct self.assertEquals(dct.get('result'), 3) + def testGenExp(self): + c = compiler.compile('list((i,j) for i in range(3) if i < 3' + ' for j in range(4) if j > 2)', + '<string>', + 'eval') + self.assertEquals(eval(c), [(0, 3), (1, 3), (2, 3)]) + NOLINENO = (compiler.ast.Module, compiler.ast.Stmt, compiler.ast.Discard) |