[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*
members.

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
or
    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;
		Py_INCREF(val);
	}

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