Skip to content

Bad code generated for except +* function #3065

@navytux

Description

@navytux

Hello up there. Please consider the following example:

---- 8< ---- (y.pyx)

# cython: language_level=2
# distutils: language=c++

cdef extern from *:
    """
    #include <exception>
    void ggg() {
        throw std::bad_alloc();
    }
    """
    void ggg()

cdef void fff() except *:
    raise RuntimeError('aaa')

cdef void hhh() except +*:
    fff()
    ggg()

def aaa():
    hhh()

Explanation:

  • ggg throws C++ exception and is not marked with except + -- thus functions that calls ggg may throw C++ exception themselves;
  • fff raises Python exception but returns void. It thus is marked with except * for its caller to check whether Python exception occurred.
  • hhh calls both fff and ggg. It thus may raise either Python exception (from fff) or C++ exception (from ggg). hhh is thus marked as except +*.

When trying to cythonize y.pyx, it gives:

/home/kirr/tmp/trashme/pyx/y.cpp: In function ‘void __pyx_f_1y_hhh()’:
/home/kirr/tmp/trashme/pyx/y.cpp:1189:3: error: ‘__pyx_r’ was not declared in this scope
   __pyx_r = <Cython.Compiler.ExprNodes.CharNode object at 0x7f8e76e20810>;
   ^~~~~~~
/home/kirr/tmp/trashme/pyx/y.cpp:1189:3: note: suggested alternative: ‘__pyx_f’
   __pyx_r = <Cython.Compiler.ExprNodes.CharNode object at 0x7f8e76e20810>;
   ^~~~~~~
   __pyx_f
/home/kirr/tmp/trashme/pyx/y.cpp:1189:13: error: expected primary-expression before ‘<’ token
   __pyx_r = <Cython.Compiler.ExprNodes.CharNode object at 0x7f8e76e20810>;
             ^
/home/kirr/tmp/trashme/pyx/y.cpp:1189:14: error: ‘Cython’ was not declared in this scope
   __pyx_r = <Cython.Compiler.ExprNodes.CharNode object at 0x7f8e76e20810>;
              ^~~~~~
/home/kirr/tmp/trashme/pyx/y.cpp: In function ‘PyObject* __pyx_pf_1y_aaa(PyObject*)’:
/home/kirr/tmp/trashme/pyx/y.cpp:1229:5: error: ‘__Pyx_CppExn2PyErr’ was not declared in this scope
     __Pyx_CppExn2PyErr();
     ^~~~~~~~~~~~~~~~~~

With the following code generated for hhh:

static void __pyx_f_1y_hhh(void) {
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("hhh", 0);

  /* "y.pyx":17
 * 
 * cdef void hhh() except +*:
 *     fff()             # <<<<<<<<<<<<<<
 *     ggg()
 * 
 */
  __pyx_f_1y_fff(); if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 17, __pyx_L1_error)

  /* "y.pyx":18
 * cdef void hhh() except +*:
 *     fff()
 *     ggg()             # <<<<<<<<<<<<<<
 * 
 * def aaa():
 */
  ggg();

  /* "y.pyx":16
 *     raise RuntimeError('aaa')
 * 
 * cdef void hhh() except +*:             # <<<<<<<<<<<<<<
 *     fff()
 *     ggg()
 */

  /* function exit code */
  goto __pyx_L0;
  __pyx_L1_error:;
  __Pyx_AddTraceback("y.hhh", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = <Cython.Compiler.ExprNodes.CharNode object at 0x7f8e76e20810>;
  __pyx_L0:;
  __Pyx_RefNannyFinishContext();
}

Notice the __pyx_r = <Cython.Compiler.ExprNodes.CharNode object at 0x7f8e76e20810>; line.

Cython version: 0.29.13-514-gac1c9fe47 (today's master).

Thanks beforehand,
Kirill

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions