From: Vitja Makarov Date: Mon, 13 Dec 2010 17:50:41 +0000 (+0300) Subject: Fix error handling add error tests X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=cd36e80c5f4d622ff66ddb494935c03a0a774495;p=cython.git Fix error handling add error tests --- diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py index 2fde811b..bd45bae1 100755 --- a/Cython/Compiler/ExprNodes.py +++ b/Cython/Compiler/ExprNodes.py @@ -4978,11 +4978,15 @@ class YieldExprNode(ExprNode): # # 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) diff --git a/Cython/Compiler/ParseTreeTransforms.py b/Cython/Compiler/ParseTreeTransforms.py index 60cee2b0..39cf2ffb 100644 --- a/Cython/Compiler/ParseTreeTransforms.py +++ b/Cython/Compiler/ParseTreeTransforms.py @@ -1308,22 +1308,23 @@ class YieldNodeCollector(TreeVisitor): 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 @@ -1348,6 +1349,8 @@ class MarkClosureVisitor(CythonTransform): 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 diff --git a/tests/errors/e_generators.pyx b/tests/errors/e_generators.pyx new file mode 100644 index 00000000..5cee59dc --- /dev/null +++ b/tests/errors/e_generators.pyx @@ -0,0 +1,24 @@ +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 +"""