[Python-Dev] problem with recursive "yield from" delegation

Stefan Behnel stefan_ml at behnel.de
Thu Mar 8 20:00:12 CET 2012


Stefan Behnel, 07.03.2012 21:40:
> I found a problem in the current "yield from" implementation

... and here's another one, also in genobject.c:

"""
int
PyGen_FetchStopIterationValue(PyObject **pvalue) {
    PyObject *et, *ev, *tb;
    PyObject *value = NULL;

    if (PyErr_ExceptionMatches(PyExc_StopIteration)) {
        PyErr_Fetch(&et, &ev, &tb);
        Py_XDECREF(et);
        Py_XDECREF(tb);
        if (ev) {
            value = ((PyStopIterationObject *)ev)->value;
            Py_INCREF(value);
            Py_DECREF(ev);
        }
    } else if (PyErr_Occurred()) {
        return -1;
    }
    if (value == NULL) {
        value = Py_None;
        Py_INCREF(value);
    }
    *pvalue = value;
    return 0;
}
"""

When the StopIteration was set using PyErr_SetObject(), "ev" points to the
value, not the exception instance, so this code lacks exception
normalisation. I use slightly different code in Cython (which needs to be
compatible with Py2.x), but CPython 3.3 could do something along these lines:

"""
        if (ev) {
            if (PyObject_IsInstance(ev, PyExc_StopIteration)) {
                value = ((PyStopIterationObject *)ev)->value;
                Py_INCREF(value); // or maybe XINCREF()?
                Py_DECREF(ev);
            } else {
                /* PyErr_SetObject() puts the value directly into ev */
                value = ev;
            }
        } else ...
"""

Would that be acceptable for CPython as well or would you prefer full
fledged normalisation?

Stefan



More information about the Python-Dev mailing list