=?utf-8?q?=5Bpygobject=5D_Accept_=C2=B1inf_and_NaN_as_float_and_double_va?= =?utf-8?q?lues?=
- From: Martin Pitt <martinpitt src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pygobject] Accept Âinf and NaN as float and double values
- Date: Wed, 23 Jan 2013 13:57:40 +0000 (UTC)
commit e65c124893ceaa9c97eb4c8c743fbeb756b9a6e6
Author: Martin Pitt <martinpitt gnome org>
Date: Wed Jan 23 14:56:02 2013 +0100
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
gi/pygi-marshal-from-py.c | 37 +++++++++++++++++++------------------
tests/test_gobject.py | 14 ++++++++++++++
2 files changed, 33 insertions(+), 18 deletions(-)
---
diff --git a/gi/pygi-marshal-from-py.c b/gi/pygi-marshal-from-py.c
index a676123..c14455c 100644
--- a/gi/pygi-marshal-from-py.c
+++ b/gi/pygi-marshal-from-py.c
@@ -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_;
diff --git a/tests/test_gobject.py b/tests/test_gobject.py
index a05d758..ec4cb44 100644
--- a/tests/test_gobject.py
+++ b/tests/test_gobject.py
@@ -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)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]