[capi-sig] Getting Numbers in C
Campbell Barton
cbarton at metavr.com
Fri Jul 20 23:30:16 CEST 2007
Campbell Barton wrote:
> Hrvoje Niksic wrote:
>>> double PyNumber_AsDouble(PyObject * value)
>>> {
>>> if (PyFloat_Check(value) || PyInt_Check(value)) {
>>> return PyFloat_AsDouble(value);
>>> } else {
>>> PyObject *pyfloat;
>>> double d;
>>>
>>> pyfloat = PyNumber_Float(value);
>>> d = PyNumber_AsDouble(pyfloat);
>> I assume this should be PyFloat_AsDouble?
>>
>>> Py_XDECREF(pyfloat);
>>> return d;
>>> }
>>> }
>> What happens if PyNumber_Float raises an exception? As far as I can
>> tell, PyNumber_AsDouble will result in a "bad argument" exception
>> being raised and will return -1, losing track of the original
>> exception in the process.
>>
>> Come to think of it, error checking problems could very well be the
>> reason why the API doesn't provide a PyNumber_AsDouble.
>
> It is a problem but I dont think thats a good enough reason not to have
> some way to do this since its such a common operation.
>
> PyFloat_AsDouble cant return an error value, so enforcing that the
> pyobject is checked with PyNumber_Check seems reasonable to me.
To follow up on this issue, Iv added the function below to a branch of
the Blender/Py API so Numbers that aren't pythons Ints of Floats work.
-----------------------------------------------------
double EXPP_PyNumber_AsDouble(PyObject * value)
{
if (PyFloat_Check(value) || PyInt_Check(value)) {
return PyFloat_AS_DOUBLE(value);
} else {
PyObject *pyfloat;
double d;
pyfloat = PyNumber_Float(value);
d = PyFloat_AsDouble(pyfloat);
Py_XDECREF(pyfloat);
return d; /* will be -1 and set an error if its PyNumber_Float failed */
}
}
-----------------------------------------------------
from looking at pythons source there are 2 ways to make sure this
function succeeds.
I was under the impression the only way to do error checking for this
was to do....
float f;
if (!PyFloat_Check(pyob)) {
PyErr_SetString(PyExc_TypeError, "float argument required");
return -1;
}
f = PyFloat_AS_DOUBLE(pyob)
But another way to do it is.... (used in python 2.5.1's stringobject.c:4150)
float f = PyFloat_Check(pyob);
if (f == -1.0 && PyErr_Occurred()) {
PyErr_SetString(PyExc_TypeError, "float argument required");
return -1;
}
Which would work with EXPP_PyNumber_AsDouble to do error checking as
well. so I think error checking is ok with that function. (and would
like to see PyNumber_AsDouble in the C/Python API hint, hint)
However Im wondering if this is advisable,
with PyErr_Occurred() its possible that some other part of the API (even
a totaly separate API) sets the error string but dosnt return an error
value. - Any suggestions?
More information about the capi-sig
mailing list