• Matěj Laitl's avatar
    Fix error propagation from memoryview-returning functions · fb8eba69
    Matěj Laitl authored
    A code like
    |cdef double[:] foo():
    |    raise AttributeError('dummy')
    
    generated C code like this:
    |  __pyx_L1_error:;
    |  (...)
    |  __pyx_r.memview = NULL;
    |  __Pyx_AddTraceback("view_return_errors.foo", __pyx_clineno, __pyx_lineno, __pyx_filename);
    |  __pyx_L0:;
    |  if (unlikely(!__pyx_r.memview)) {
    |    PyErr_SetString(PyExc_TypeError,"Memoryview return value is not initialized");
    |  }
    |  __Pyx_RefNannyFinishContext();
    |  return __pyx_r;
    |}
    
    Which is incorrect in error case, because we set __pyx_r.memview to NULL and
    then we test it, so that the PyErr_SetString() is always called in the error
    case, which swallows previously-set error. (it also swallowed the traceback,
    which I don't understand)
    
    A fix is to jump to return_from_error_cleanup label in case return type is
    memoryview, as it is currently done for the case when buffers are present.
    
    A testcase that fauils w/out this fix applied is included, too.
    
    v2: fix test under Python 3 by not using StandardError
    
    --HG--
    extra : transplant_source : G%B5%99Og%D1%81%25k%8F%1F%7B%02V%3E%B9%A4y%FF%EA
    fb8eba69
Nodes.py 318 KB