Hi,
what am I doing wrong?
static PyObject *is_prime(PyObject *self, PyObject *value) { if (!PyInt_Check(value)) { PyErr_SetString(PyExc_TypeError, "only integers are acceptable"); return NULL; }
primes.is_prime(3)
Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: only integers are acceptable
Thanks
On Sun, May 23, 2010 at 7:40 AM, Vojtěch Rylko vojta.rylko@seznam.cz wrote:
what am I doing wrong?
C code:
static PyObject *is_prime(PyObject *self, PyObject *value) { if (!PyInt_Check(value)) { PyErr_SetString(PyExc_TypeError, "only integers are acceptable"); return NULL; }
Test (I'm using integer 3):
primes.is_prime(3)
Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: only integers are acceptable
The second argument ('value', in your code) is actually a tuple containing the arguments passed to your is_prime() function. You'll need to unpack the individual values from that tuple.
http://docs.python.org/extending/extending.html#extracting-parameters-in-ext...
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);
Dne 24.5.2010 8:56, Jon Parise napsal(a):
On Sun, May 23, 2010 at 7:40 AM, Vojtěch Rylkovojta.rylko@seznam.cz wrote:
what am I doing wrong?
C code:
static PyObject *is_prime(PyObject *self, PyObject *value) { if (!PyInt_Check(value)) { PyErr_SetString(PyExc_TypeError, "only integers are acceptable"); return NULL; }
Test (I'm using integer 3):
primes.is_prime(3)
Traceback (most recent call last): File "<stdin>", line 1, in<module> ValueError: only integers are acceptable
The second argument ('value', in your code) is actually a tuple containing the arguments passed to your is_prime() function. You'll need to unpack the individual values from that tuple.
http://docs.python.org/extending/extending.html#extracting-parameters-in-ext...
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
On Mon, May 24, 2010 at 6:31 AM, Vojtěch Rylko vojta.rylko@seznam.czwrote:
PyObject *value; if (!PyArg_ParseTuple(arg, "O", value))
Daniel Stutzbach, Ph.D. President, Stutzbach Enterprises, LLC http://stutzbachenterprises.com
You are right, thank you very much.
Vojtěch Rylko
Dne 24.5.2010 15:50, Daniel Stutzbach napsal(a):
On Mon, May 24, 2010 at 6:31 AM, Vojtěch Rylko <vojta.rylko@seznam.cz mailto:vojta.rylko@seznam.cz> wrote:
PyObject *value; if (!PyArg_ParseTuple(arg, "O", value))
Shouldn't that be "&value"?
Daniel Stutzbach, Ph.D. President, Stutzbach Enterprises, LLC http://stutzbachenterprises.com
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