}
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)
{