From: Benjamin Peterson Date: Thu, 3 May 2012 22:44:33 +0000 (-0400) Subject: merge 3.2 (#14717) X-Git-Tag: v3.3.0a4~296 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9cd8853d45724ea9d92d50aa866ee201aba6cbdc;p=python merge 3.2 (#14717) --- 9cd8853d45724ea9d92d50aa866ee201aba6cbdc diff --cc Objects/genobject.c index 0fc14db89e,6e25f13475..8c70b5ca10 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@@ -137,58 -129,8 +137,58 @@@ _PyGen_Send(PyGenObject *gen, PyObject } PyDoc_STRVAR(close_doc, - "close(arg) -> raise GeneratorExit inside generator."); + "close() -> raise GeneratorExit inside generator."); +/* + * This helper function is used by gen_close and gen_throw to + * close a subiterator being delegated to by yield-from. + */ + +static int +gen_close_iter(PyObject *yf) +{ + PyObject *retval = NULL; + + if (PyGen_CheckExact(yf)) { + retval = gen_close((PyGenObject *)yf, NULL); + if (retval == NULL) + return -1; + } else { + PyObject *meth = PyObject_GetAttrString(yf, "close"); + if (meth == NULL) { + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) + PyErr_WriteUnraisable(yf); + PyErr_Clear(); + } else { + retval = PyObject_CallFunction(meth, ""); + Py_DECREF(meth); + if (retval == NULL) + return -1; + } + } + Py_XDECREF(retval); + return 0; +} + +static PyObject * +gen_yf(PyGenObject *gen) +{ + PyObject *yf = NULL; + PyFrameObject *f = gen->gi_frame; + + if (f) { + PyObject *bytecode = f->f_code->co_code; + unsigned char *code = (unsigned char *)PyBytes_AS_STRING(bytecode); + + if (code[f->f_lasti + 1] != YIELD_FROM) + return NULL; + yf = f->f_stacktop[-1]; + Py_INCREF(yf); + } + + return yf; +} + static PyObject * gen_close(PyGenObject *gen, PyObject *args) {