[capi-sig] Getting Numbers in C

Campbell Barton cbarton at metavr.com
Sat Jul 21 04:33:35 CEST 2007

Hrvoje Niksic wrote:
> Campbell Barton <cbarton at metavr.com> writes:
>> 		pyfloat = PyNumber_Float(value);
> It might be a good idea to return -1 immediately if this returns
> NULL.  That way you prevent clobbering the real exception with an
> "invalid argument" exception returned by PyFloat_AsDouble.
I think your right, whats there should work but it could return -1 early.

> If PyNumber_Float succeeds, but pyfloat turns out not to be float,
> then the invalid argument exception is perfectly fine.

Is this possible? - if its a number type I would have thaught it must be 
able to be converted to a float.

>> 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?
> Requiring the caller to check for PyErr_Occurred seems like bad style,
> but I'm not sure that it's an actual problem, as long as it's clearly
> documented.

Lots of Pythons internal code and modules do this. see hows 
PyFloat_AsDouble's  used in  cfield.c, _struct.c, datetimemodule.c, 
selectmodule.c, socketmodule.c.....  and others but look in those to see 
that its used. It looked like bad coding style to me too.

> As far as I know, no part of the API is allowed to set the error
> string and not return an error value because that breaks other parts
> of Python.  Consider this function:
> static PyObject *
> test()
> {
>   PyErr_SetString(PyExc_TypeError, "test");
>   Py_INCREF(Py_None);
>   return Py_None;
> }
> Calling it subtly breaks Python:
>>>> import foo
>>>> foo.test()
>>>> import sys
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
> TypeError: test
> The exception lingered until the first function that relies on
> PyErr_Occurred() to test for an exception, in this case PyImport_*.

your example will mess things up but the way the API works (it seems), 
is you have functions to work around this and return the correct error 
values with functions that interface python.

PyFloat_AsDouble - assumes the type is a PyFloat, if its not compatible 
it WILL set the error string and leaves the API to see if the error 
string is set and return an error value (-1 or NULL depending on the 
type of function).

More information about the capi-sig mailing list