From cd36e80c5f4d622ff66ddb494935c03a0a774495 Mon Sep 17 00:00:00 2001 From: Vitja Makarov Date: Mon, 13 Dec 2010 20:50:41 +0300 Subject: [PATCH] Fix error handling add error tests --- Cython/Compiler/ExprNodes.py | 4 ++++ Cython/Compiler/ParseTreeTransforms.py | 21 ++++++++++++--------- tests/errors/e_generators.pyx | 24 ++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 9 deletions(-) create mode 100644 tests/errors/e_generators.pyx 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 +""" -- 2.26.2