[Python-Dev] Is it safe to call PyEval_EvalFrameEx() with an exception set? (original) (raw)

Victor Stinner victor.stinner at gmail.com
Tue Jul 16 02:34:49 CEST 2013


Hi,

I'm working on the issue #18408 (fix issues found by my pyfailmalloc tool). To analyze some bugs, I have to add debug traces in various functions to find which function returned NULL without setting an error, or the opposite: returned a valid object, but with an exception set.

I would like to add assertions in Python/ceval.c to detect such bugs earlier. The problem is that some functions rely on the ability to call PyEval_EvalFrameEx() with an exception set. Is it expected? Should it be avoided? The current exception can be replaced with a new exception.

Example 1:

module = PyImport_Import(module_name);
if (module == NULL) {
    PyErr_Format(PicklingError,
                 "Can't pickle %R: import of module %R failed",
                 obj, module_name);
    goto error;
}

Formatting the obj argument calls indirectly PyEval_EvalFrameEx(), whereas an ImportError was raised. The original ImportError is replaced with a new PickleError exception.

To not call PyEval_EvalFrameEx() with an exception set, PyErr_Format() can call PyErr_Clear() before calling PyUnicode_FromFormatV(), maybe only in debug mode.

Example 2:

test_sqlite uses sqlite.connection.create_aggregate() to create a Python callback called by the C sqlite3 library. The "callback" is a class with 3 methods: constructor, step() and finalize(). The test AggregateTests.CheckAggrNoStep() uses a class with no step() method: it ensures that an AttributeError is raised.

The problem is that the finalize() method is called even if the class has no step method, and so there is a current AttributeError exception.

I don't know if finalize() should be called in this case. It may be a bug in the sqlite module. More generally,

Victor



More information about the Python-Dev mailing list