[Pyrex] Pyrex exception type checking broken under Python 2.5 (and earlier)

Stefan Behnel behnel_ml at gkec.informatik.tu-darmstadt.de
Thu Jun 22 18:52:30 UTC 2006


Hi,

Pyrex uses this code in __Pyx_Raise() to check if an exception object has the
right type for being raised:

-------------------------------
    if (PyString_Check(type))
        ;
    else if (PyClass_Check(type))
        ; /*PyErr_NormalizeException(&type, &value, &tb);*/
    else if (PyInstance_Check(type)) {
        /* Raising an instance.  The value should be a dummy. */
        if (value != Py_None) {
            PyErr_SetString(PyExc_TypeError,
              "instance exception may not have a separate value");
            goto raise_error;
        }
        else {
            /* Normalize to raise <class>, <instance> */
            Py_DECREF(value);
            value = type;
            type = (PyObject*) ((PyInstanceObject*)type)->in_class;
            Py_INCREF(type);
        }
    }
    else {
        /* Not something you can raise.  You get an exception
           anyway, just not what you specified :-) */
        PyErr_Format(PyExc_TypeError,
                 "exceptions must be strings, classes, or "
                 "instances, not %s", type->ob_type->tp_name);
        goto raise_error;
    }
    PyErr_Restore(type, value, tb);
-------------------------------

The problem is that exceptions in Py2.5 have become new-style classes which no
longer fall under any of the above checks. A while ago, I proposed this patch:

Index: Pyrex/Compiler/Nodes.py
===================================================================
--- Pyrex/Compiler/Nodes.py     (Revision 131)
+++ Pyrex/Compiler/Nodes.py     (Arbeitskopie)
@@ -3650,7 +3658,7 @@
     }
     if (PyString_Check(type))
         ;
-    else if (PyClass_Check(type))
+    else if (PyType_Check(type) || PyClass_Check(type))
         ; /*PyErr_NormalizeException(&type, &value, &tb);*/
     else if (PyInstance_Check(type)) {
         /* Raising an instance.  The value should be a dummy. */


However, this is not enough. It does not allow raising /instances/ of
new-style classes. (Note that PyInstance_Check only checks for old-style
classes). Also, support for string exceptions is deprecated and supposed to be
removed in later Python versions. I therefore propose to actually remove the
above check from Pyrex completely. It does not add much safety anyway, slows
down exception raising and prevents raising new-style exceptions that Python
allowed for a while and that are now considered 'normal' by Python 2.5.

Stefan



More information about the Pyrex mailing list