summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Peterson <benjamin@python.org>2012-08-07 00:53:09 (GMT)
committerBenjamin Peterson <benjamin@python.org>2012-08-07 00:53:09 (GMT)
commitb37df519c793d40718fda78a9961811fae973f36 (patch)
treeb4a98c5e8e3e070f32a27c36c6f77daeaeb3d141
parenta0abb4404a839787bc0791c7ea3b261fcd146652 (diff)
downloadcpython-b37df519c793d40718fda78a9961811fae973f36.zip
cpython-b37df519c793d40718fda78a9961811fae973f36.tar.gz
cpython-b37df519c793d40718fda78a9961811fae973f36.tar.bz2
fix yield from return value on custom iterators (closes #15568)
-rw-r--r--Lib/test/test_pep380.py14
-rw-r--r--Misc/NEWS3
-rw-r--r--Python/ceval.c2
3 files changed, 18 insertions, 1 deletions
diff --git a/Lib/test/test_pep380.py b/Lib/test/test_pep380.py
index 658bcb9..9569e10 100644
--- a/Lib/test/test_pep380.py
+++ b/Lib/test/test_pep380.py
@@ -940,6 +940,20 @@ class TestPEP380Operation(unittest.TestCase):
for stack in spam(eggs(gen())):
self.assertTrue('spam' in stack and 'eggs' in stack)
+ def test_custom_iterator_return(self):
+ # See issue #15568
+ class MyIter:
+ def __iter__(self):
+ return self
+ def __next__(self):
+ raise StopIteration(42)
+ def gen():
+ nonlocal ret
+ ret = yield from MyIter()
+ ret = None
+ list(gen())
+ self.assertEqual(ret, 42)
+
def test_main():
from test import support
diff --git a/Misc/NEWS b/Misc/NEWS
index 6f7b0fc..d062df4 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,9 @@ What's New in Python 3.3.0 Beta 2?
Core and Builtins
-----------------
+- Issue #15568: Fix the return value of "yield from" when StopIteration is
+ raised by a custom iterator.
+
- Issue #13119: sys.stdout and sys.stderr are now using "\r\n" newline on
Windows, as Python 2.
diff --git a/Python/ceval.c b/Python/ceval.c
index 7e9318b..82bfcc6 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -1843,7 +1843,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
} else {
_Py_IDENTIFIER(send);
if (u == Py_None)
- retval = PyIter_Next(x);
+ retval = Py_TYPE(x)->tp_iternext(x);
else
retval = _PyObject_CallMethodId(x, &PyId_send, "O", u);
}