Type checking inside a C extension... doesn't throw exception on failure

Jon Perez jbperez808 at yahoo.com
Mon Apr 5 23:54:30 EDT 2004


Paul Prescod wrote:

> It isn't true that PyLong_AsLong does no type checking. It does. It 
> reports problems through the standard Python exception system.

This illustrates a case where a crash occurs instead of an
exception being thrown.  Feed spam.getstring() something besides a
string:

static PyObject *spam_getstring(PyObject *self, PyObject *args) {
   PyObject *tup, *a, *b;

   char strstr[100];

   if (!PyArg_ParseTuple(args, "O", &strobj))
     return NULL;

   // PyString_AsString(strobj);  // raises exception
   strcpy(strstr,PyString_AsString(strobj));  /* crashes!! */

   Py_INCREF(Py_None);
   return Py_None;
}

What gives? Shouldn't the exception be raised within PyString_AsString()
before it even gets a chance to return a value to strcpy()?  (Note:
I have been using IDLE - in the default separate subprocess mode - to observe
this behaviour)


Assuming I am resigned to calling PyString_Check() myself, can I
avoid the redundant PyString_Check() that PyString_AsString() is
probably calling?

> PyLong_Check is pretty cheap:
> 
> #define PyObject_TypeCheck(ob, tp) \
>         ((ob)->ob_type == (tp) || PyType_IsSubtype((ob)->ob_type, (tp)))
> #define PyLong_Check(op) PyObject_TypeCheck(op, &PyLong_Type)

Kewl...

> it generates code like this:
> 
>   /* "/private/tmp/foo.pyx":3 */
>   __pyx_1 = PyInt_AsLong(__pyx_v_b);
>   if (PyErr_Occurred()) {error handling and return}
> 
> By PyErr_Occurred() is a real function call and is probably slower than 
> PyLong_Check.

Is PyType_IsSubtype((ob)->ob_Type,(tp))) a real function call as well though?




More information about the Python-list mailing list