#
# arg ExprNode the value to return from the generator
# label_name string name of the C label used for this yield
+ # label_num integer yield label number
subexprs = ['arg']
type = py_object_type
+ label_num = 0
def analyse_types(self, env):
+ if not self.label_num:
+ error(self.pos, "'yield' not supported here")
self.is_temp = 1
if self.arg is not None:
self.arg.analyse_types(env)
def __init__(self):
super(YieldNodeCollector, self).__init__()
self.yields = []
- self.has_return = False
+ self.returns = []
+ self.has_return_value = False
visit_Node = TreeVisitor.visitchildren
def visit_YieldExprNode(self, node):
- if self.has_return:
+ if self.has_return_value:
error(node.pos, "'yield' outside function")
- else:
- self.yields.append(node)
- node.label_num = len(self.yields)
+ self.yields.append(node)
+ node.label_num = len(self.yields)
def visit_ReturnStatNode(self, node):
- if self.yields:
- error(collector.returns[0].pos, "'return' with argument inside generator")
- else:
- self.has_return = True
+ if node.value:
+ self.has_return_value = True
+ if self.yields:
+ error(node.pos, "'return' with argument inside generator")
+ self.returns.append(node)
def visit_ClassDefNode(self, node):
pass
collector.visitchildren(node)
if collector.yields:
+ if collector.returns and not collector.has_return_value:
+ error(collector.returns[0].pos, "'return' inside generators not yet supported ")
node.is_generator = True
node.needs_closure = True
node.yields = collector.yields
--- /dev/null
+def foo():
+ yield
+ return 0
+
+def bar(a):
+ return 0
+ yield
+
+def xxx():
+ yield
+ return
+
+yield
+
+class Foo:
+ yield
+
+_ERRORS = u"""
+3:4: 'return' with argument inside generator
+7:4: 'yield' outside function
+11:4: 'return' inside generators not yet supported
+13:0: 'yield' not supported here
+16:4: 'yield' not supported here
+"""