Author: Jeremy Thurgood <fir...@gmail.com> Branch: remove-del-from-generatoriterator Changeset: r68716:b3bc55c98005 Date: 2014-01-17 11:17 +0200 http://bitbucket.org/pypy/pypy/changeset/b3bc55c98005/
Log: add a CO_YIELD_INSIDE_TRY code flag diff --git a/pypy/interpreter/astcompiler/codegen.py b/pypy/interpreter/astcompiler/codegen.py --- a/pypy/interpreter/astcompiler/codegen.py +++ b/pypy/interpreter/astcompiler/codegen.py @@ -1234,6 +1234,8 @@ flags |= consts.CO_NESTED if scope.is_generator: flags |= consts.CO_GENERATOR + if scope.has_yield_inside_try: + flags |= consts.CO_YIELD_INSIDE_TRY if scope.has_variable_arg: flags |= consts.CO_VARARGS if scope.has_keywords_arg: diff --git a/pypy/interpreter/astcompiler/consts.py b/pypy/interpreter/astcompiler/consts.py --- a/pypy/interpreter/astcompiler/consts.py +++ b/pypy/interpreter/astcompiler/consts.py @@ -17,6 +17,7 @@ CO_FUTURE_UNICODE_LITERALS = 0x20000 #pypy specific: CO_KILL_DOCSTRING = 0x100000 +CO_YIELD_INSIDE_TRY = 0x200000 PyCF_SOURCE_IS_UTF8 = 0x0100 PyCF_DONT_IMPLY_DEDENT = 0x0200 diff --git a/pypy/interpreter/astcompiler/symtable.py b/pypy/interpreter/astcompiler/symtable.py --- a/pypy/interpreter/astcompiler/symtable.py +++ b/pypy/interpreter/astcompiler/symtable.py @@ -43,6 +43,7 @@ self.child_has_free = False self.nested = False self.doc_removable = False + self._visiting_try_body = False def lookup(self, name): """Find the scope of identifier 'name'.""" @@ -75,6 +76,14 @@ self.varnames.append(mangled) return mangled + def note_try_start(self, try_node): + """Called when a try is found, before visiting the body.""" + self._visiting_try_body = True + + def note_try_end(self, try_node): + """Called after visiting a try body.""" + self._visiting_try_body = False + def note_yield(self, yield_node): """Called when a yield is found.""" raise SyntaxError("'yield' outside function", yield_node.lineno, @@ -210,6 +219,7 @@ self.has_variable_arg = False self.has_keywords_arg = False self.is_generator = False + self.has_yield_inside_try = False self.optimized = True self.return_with_value = False self.import_star = None @@ -220,6 +230,8 @@ raise SyntaxError("'return' with argument inside generator", self.ret.lineno, self.ret.col_offset) self.is_generator = True + if self._visiting_try_body: + self.has_yield_inside_try = True def note_return(self, ret): if ret.value: @@ -505,3 +517,16 @@ else: role = SYM_ASSIGNED self.note_symbol(name.id, role) + + def visit_TryExcept(self, node): + self.scope.note_try_start(node) + self.visit_sequence(node.body) + self.scope.note_try_end(node) + self.visit_sequence(node.handlers) + self.visit_sequence(node.orelse) + + def visit_TryFinally(self, node): + self.scope.note_try_start(node) + self.visit_sequence(node.body) + self.scope.note_try_end(node) + self.visit_sequence(node.finalbody) diff --git a/pypy/interpreter/astcompiler/test/test_symtable.py b/pypy/interpreter/astcompiler/test/test_symtable.py --- a/pypy/interpreter/astcompiler/test/test_symtable.py +++ b/pypy/interpreter/astcompiler/test/test_symtable.py @@ -346,6 +346,14 @@ assert exc.msg == "'return' with argument inside generator" scp = self.func_scope("def f():\n return\n yield x") + def test_yield_inside_try(self): + scp = self.func_scope("def f(): yield x") + assert not scp.has_yield_inside_try + scp = self.func_scope("def f():\n try:\n yield x\n except: pass") + assert scp.has_yield_inside_try + scp = self.func_scope("def f():\n try:\n yield x\n finally: pass") + assert scp.has_yield_inside_try + def test_return(self): for input in ("class x: return", "return"): exc = py.test.raises(SyntaxError, self.func_scope, input).value _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit