[capi-sig] Checking int type

Stefan Behnel python_capi at behnel.de
Mon May 24 20:19:51 CEST 2010


Vojtěch Rylko, 24.05.2010 13:31:
> But after unpacking, I still cannot detect no-integer type object.
>
>  >>> from primes import is_prime
>  >>> is_prime(7)
> True
>  >>> is_prime(5.5) # should raise exception, but is rounded as 5
> __main__:1: DeprecationWarning: integer argument expected, got float
> True
>  >>> is_prime(9.8) # should raise exception, but is rounded as 9
> False
>
> =================================
> static PyObject *is_prime(PyObject *self, PyObject *arg)
> {
> PyObject *value;
> if (!PyArg_ParseTuple(arg, "O", value))
> return NULL;
>
> if (PyInt_Check(value)) {
> // never raise (test case - in real its if(!PyInt_Check(value) which
> always raise)
> PyErr_SetString(PyExc_ValueError, "only integers are acceptable");
> return NULL;
> }
> int number;
> if (!PyArg_ParseTuple(value, "i", &number))
> return NULL;
>
> int result = is_prime_solve(number);

You should consider giving Cython a try, where the above spells

     cdef extern from "yourcode.h":
          bint is_prime_solve(int number)

     def is_prime(int number):
         """
         >>> is_prime(7)
         True
         """
         return is_prime_solve(number)

It will raise a TypeError for you if a user passes something that can't 
coerce to an int, or an OverflowError for something that is too large for a 
C int. However, note that coercion to a C int means calling int() in 
Python, which also works for float values. If you *really* want to prevent 
non-int values, you can do this:

     def is_prime(number):
         if not isinstance(number, int):
             raise TypeError("please pass an int")
         return is_prime_solve(number)

Stefan


More information about the capi-sig mailing list