Commit e65c1248 authored by Martin Pitt's avatar Martin Pitt
Browse files

Accept ±inf and NaN as float and double values

Also fix the broken error message when a float value is out of range.
PyErr_Format() does not support float macros.

https://bugzilla.gnome.org/show_bug.cgi?id=692381
parent a5224538
......@@ -659,6 +659,23 @@ _pygi_marshal_from_py_uint64 (PyGIInvokeState *state,
return TRUE;
}
static gboolean
check_valid_double (double x, double min, double max)
{
char buf[100];
if ((x < min || x > max) && x != INFINITY && x != -INFINITY && x != NAN) {
if (PyErr_Occurred())
PyErr_Clear ();
/* we need this as PyErr_Format() does not support float types */
snprintf (buf, sizeof (buf), "%g not in range %g to %g", x, min, max);
PyErr_SetString (PyExc_ValueError, buf);
return FALSE;
}
return TRUE;
}
gboolean
_pygi_marshal_from_py_float (PyGIInvokeState *state,
PyGICallableCache *callable_cache,
......@@ -682,16 +699,8 @@ _pygi_marshal_from_py_float (PyGIInvokeState *state,
double_ = PyFloat_AsDouble (py_float);
Py_DECREF (py_float);
if (PyErr_Occurred ()) {
PyErr_Clear ();
PyErr_Format (PyExc_ValueError, "%f not in range %f to %f", double_, -G_MAXFLOAT, G_MAXFLOAT);
return FALSE;
}
if (double_ < -G_MAXFLOAT || double_ > G_MAXFLOAT) {
PyErr_Format (PyExc_ValueError, "%f not in range %f to %f", double_, -G_MAXFLOAT, G_MAXFLOAT);
if (PyErr_Occurred () || !check_valid_double (double_, -G_MAXFLOAT, G_MAXFLOAT))
return FALSE;
}
arg->v_float = double_;
......@@ -721,16 +730,8 @@ _pygi_marshal_from_py_double (PyGIInvokeState *state,
double_ = PyFloat_AsDouble (py_float);
Py_DECREF (py_float);
if (PyErr_Occurred ()) {
PyErr_Clear ();
PyErr_Format (PyExc_ValueError, "%f not in range %f to %f", double_, -G_MAXDOUBLE, G_MAXDOUBLE);
if (PyErr_Occurred () || !check_valid_double (double_, -G_MAXDOUBLE, G_MAXDOUBLE))
return FALSE;
}
if (double_ < -G_MAXDOUBLE || double_ > G_MAXDOUBLE) {
PyErr_Format (PyExc_ValueError, "%f not in range %f to %f", double_, -G_MAXDOUBLE, G_MAXDOUBLE);
return FALSE;
}
arg->v_double = double_;
......
......@@ -624,10 +624,24 @@ class TestGValue(unittest.TestCase):
# python float is G_TYPE_DOUBLE
value = GObject.Value(float, 23.4)
self.assertEqual(value.g_type, GObject.TYPE_DOUBLE)
value.set_value(1e50)
self.assertAlmostEqual(value.get_value(), 1e50)
value = GObject.Value(GObject.TYPE_FLOAT, 23.4)
self.assertEqual(value.g_type, GObject.TYPE_FLOAT)
self.assertRaises(TypeError, value.set_value, 'string')
self.assertRaises(ValueError, value.set_value, 1e50)
def test_float_inf_nan(self):
nan = float('nan')
for type_ in [GObject.TYPE_FLOAT, GObject.TYPE_DOUBLE]:
for x in [float('inf'), float('-inf'), nan]:
value = GObject.Value(type_, x)
# assertEqual() is False for (nan, nan)
if x is nan:
self.assertEqual(str(value.get_value()), 'nan')
else:
self.assertEqual(value.get_value(), x)
def test_enum(self):
value = GObject.Value(GLib.FileError, GLib.FileError.FAILED)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment