Author: Jeremy Thurgood <[email protected]>
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
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit