[Python-Dev] Low-level exception invariants?

Tim Peters tim.peters at gmail.com
Fri May 26 18:19:14 CEST 2006

In various places we store triples of exception info, like a
PyFrameObject's f_exc_type, f_exc_value, and f_exc_traceback PyObject*

No invariants are documented, and that's a shame.  Patch 1145039 aims
to speed ceval a bit by relying on a weak guessed invariant, but I'd
like to make the stronger claim (which allows for stronger speedups)
that, at any moment,

    all three are NULL
    all three are not NULL

Now I know that's not true, although Python's test suite doesn't
provoke a violation.  In particular, PyErr_SetNone() forces
tstate->curexc_value to NULL.  Other code then special-cases the snot
out of XYZ_value, replacing NULL with Py_None on the fly, like

	PyErr_Fetch(&exc, &val, &tb);
	if (val == NULL) {
		val = Py_None;

in the main eval loop.  I'd much rather change PyErr_SetNone() to set
the value to Py_None to begin with -- that function is almost never
called, so special-casing in that is less damaging than special-casing
NULL everywhere else.

The docs are confused about this now too, claiming:

void PyErr_SetNone(PyObject *type)
    This is a shorthand for "PyErr_SetObject(type, Py_None)".

It's actually a shorthand for PyErr_SetObject(type, NULL) now.

Does anyone see a real problem with _establishing_ an "all NULL or
none NULL" invariant?  It makes outstanding ;-) _conceptual_ sense to
me, and would allow removing some masses of distributed test-branch
special-casing in code trying to use these guys.

More information about the Python-Dev mailing list