Mercurial > cpython-lru_cache-weakref
diff Python/ceval.c @ 74356:d64ac9ab4cd0
Implement PEP 380 - 'yield from' (closes #11682)
| author | Nick Coghlan <ncoghlan@gmail.com> |
|---|---|
| date | Fri, 13 Jan 2012 21:43:40 +1000 |
| parents | e1dbc72bd97f |
| children | 315781cd72fa |
line wrap: on
line diff
--- a/Python/ceval.c Thu Jan 12 21:10:29 2012 -0500 +++ b/Python/ceval.c Fri Jan 13 21:43:40 2012 +1000 @@ -1828,6 +1828,52 @@ why = WHY_RETURN; goto fast_block_end; + TARGET(YIELD_FROM) + u = POP(); + x = PyObject_GetIter(u); + Py_DECREF(u); + if (x == NULL) + break; + /* x is now the iterator, make the first next() call */ + retval = (*Py_TYPE(x)->tp_iternext)(x); + if (!retval) { + /* iter may be exhausted */ + Py_CLEAR(x); + if (!PyErr_ExceptionMatches(PyExc_StopIteration)) { + /* some other exception */ + break; + } + /* try to get return value from exception */ + PyObject *et, *ev, *tb; + PyErr_Fetch(&et, &ev, &tb); + Py_XDECREF(et); + Py_XDECREF(tb); + /* u is return value */ + u = NULL; + if (ev) { + u = PyObject_GetAttrString(ev, "value"); + Py_DECREF(ev); + if (u == NULL) { + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) { + /* some other exception */ + break; + } + PyErr_Clear(); + } + } + if (u == NULL) { + u = Py_None; + Py_INCREF(u); + } + PUSH(u); + continue; + } + /* x is iterator, retval is value to be yielded */ + f->f_yieldfrom = x; + f->f_stacktop = stack_pointer; + why = WHY_YIELD; + goto fast_yield; + TARGET(YIELD_VALUE) retval = POP(); f->f_stacktop = stack_pointer;
