Commit e7a92df0 authored by Stefan Behnel's avatar Stefan Behnel

avoid setting explicit "None" as StopIteration exception value in generators...

avoid setting explicit "None" as StopIteration exception value in generators and directly return NULL instead
parent e5fc5239
...@@ -5501,10 +5501,10 @@ class ReturnStatNode(StatNode): ...@@ -5501,10 +5501,10 @@ class ReturnStatNode(StatNode):
have_gil=self.in_nogil_context) have_gil=self.in_nogil_context)
elif self.in_generator: elif self.in_generator:
# return value == raise StopIteration(value), but uncatchable # return value == raise StopIteration(value), but uncatchable
code.putln( code.putln("%s = NULL;" % Naming.retval_cname)
"%s = NULL; PyErr_SetObject(PyExc_StopIteration, %s);" % ( if not self.value.is_none:
Naming.retval_cname, code.putln("PyErr_SetObject(PyExc_StopIteration, %s);" %
self.value.result_as(self.return_type))) self.value.result_as(self.return_type))
self.value.generate_disposal_code(code) self.value.generate_disposal_code(code)
else: else:
self.value.make_owned_reference(code) self.value.make_owned_reference(code)
...@@ -5516,7 +5516,10 @@ class ReturnStatNode(StatNode): ...@@ -5516,7 +5516,10 @@ class ReturnStatNode(StatNode):
self.value.free_temps(code) self.value.free_temps(code)
else: else:
if self.return_type.is_pyobject: if self.return_type.is_pyobject:
code.put_init_to_py_none(Naming.retval_cname, self.return_type) if self.in_generator:
code.putln("%s = NULL;" % Naming.retval_cname)
else:
code.put_init_to_py_none(Naming.retval_cname, self.return_type)
elif self.return_type.is_returncode: elif self.return_type.is_returncode:
self.put_return(code, self.return_type.default_value) self.put_return(code, self.return_type.default_value)
......
...@@ -293,6 +293,7 @@ def test_decorated(*args): ...@@ -293,6 +293,7 @@ def test_decorated(*args):
for i in args: for i in args:
yield i yield i
def test_return(a): def test_return(a):
""" """
>>> d = dict() >>> d = dict()
...@@ -309,6 +310,59 @@ def test_return(a): ...@@ -309,6 +310,59 @@ def test_return(a):
a['i_was_here'] = True a['i_was_here'] = True
return return
def test_return_in_finally(a):
"""
>>> d = dict()
>>> obj = test_return_in_finally(d)
>>> next(obj)
1
>>> next(obj)
Traceback (most recent call last):
StopIteration
>>> d['i_was_here']
True
>>> obj = test_return_in_finally(None)
>>> next(obj)
1
>>> next(obj)
Traceback (most recent call last):
StopIteration
"""
yield 1
try:
a['i_was_here'] = True
finally:
return
def test_return_none_in_finally(a):
"""
>>> d = dict()
>>> obj = test_return_none_in_finally(d)
>>> next(obj)
1
>>> next(obj)
Traceback (most recent call last):
StopIteration
>>> d['i_was_here']
True
>>> obj = test_return_none_in_finally(None)
>>> next(obj)
1
>>> next(obj)
Traceback (most recent call last):
StopIteration
"""
yield 1
try:
a['i_was_here'] = True
finally:
return None
def test_copied_yield(foo): def test_copied_yield(foo):
""" """
>>> class Manager(object): >>> class Manager(object):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment