[pygobject/set-value-unify: 3/3] Value.get/set_value: use _gvalue_get/set in more cases



commit 125e679722f4628ce20baacb179a3675ca0c0863
Author: Christoph Reiter <reiter christoph gmail com>
Date:   Sat Jan 19 14:21:56 2019 +0100

    Value.get/set_value: use _gvalue_get/set in more cases
    
    It's a bit faster and is a good chance to make sure both marshalling
    paths behave the same and add some tests.
    
    No functional change intended.

 gi/overrides/GObject.py         |  93 +++++---------------
 tests/test_overrides_gobject.py | 190 ++++++++++++++++++++++++++++++++++------
 2 files changed, 184 insertions(+), 99 deletions(-)
---
diff --git a/gi/overrides/GObject.py b/gi/overrides/GObject.py
index 20a92b0e..81f214f0 100644
--- a/gi/overrides/GObject.py
+++ b/gi/overrides/GObject.py
@@ -233,57 +233,28 @@ class Value(GObjectModule.Value):
     def set_value(self, py_value):
         gtype = self.__g_type
 
-        if gtype == _gi.TYPE_INVALID:
-            raise TypeError("GObject.Value needs to be initialized first")
-        elif gtype == TYPE_BOOLEAN:
-            self.set_boolean(py_value)
-        elif gtype == TYPE_CHAR:
+        if gtype == TYPE_CHAR:
             self.set_char(py_value)
         elif gtype == TYPE_UCHAR:
             self.set_uchar(py_value)
-        elif gtype == TYPE_INT:
-            self.set_int(py_value)
-        elif gtype == TYPE_UINT:
-            self.set_uint(py_value)
-        elif gtype == TYPE_LONG:
-            self.set_long(py_value)
-        elif gtype == TYPE_ULONG:
-            self.set_ulong(py_value)
-        elif gtype == TYPE_INT64:
-            self.set_int64(py_value)
-        elif gtype == TYPE_UINT64:
-            self.set_uint64(py_value)
-        elif gtype == TYPE_FLOAT:
-            self.set_float(py_value)
-        elif gtype == TYPE_DOUBLE:
-            self.set_double(py_value)
         elif gtype == TYPE_STRING:
-            if py_value is None or isinstance(py_value, str):
-                py_value = py_value
-            elif PY2:
-                if isinstance(py_value, text_type):
-                    py_value = py_value.encode('UTF-8')
+            if not isinstance(py_value, str) and py_value is not None:
+                if PY2:
+                    if isinstance(py_value, text_type):
+                        py_value = py_value.encode('UTF-8')
+                    else:
+                        raise TypeError("Expected string or unicode but got %s%s" %
+                                        (py_value, type(py_value)))
                 else:
-                    raise TypeError("Expected string or unicode but got %s%s" %
+                    raise TypeError("Expected string but got %s%s" %
                                     (py_value, type(py_value)))
-            else:
-                raise TypeError("Expected string but got %s%s" %
-                                (py_value, type(py_value)))
-            self.set_string(py_value)
+            _gi._gvalue_set(self, py_value)
         elif gtype == TYPE_PARAM:
             self.set_param(py_value)
-        elif gtype == TYPE_PYOBJECT:
-            self.set_boxed(py_value)
-        elif gtype.is_a(TYPE_ENUM):
-            self.set_enum(py_value)
         elif gtype.is_a(TYPE_FLAGS):
             self.set_flags(py_value)
-        elif gtype.is_a(TYPE_BOXED):
-            self.set_boxed(py_value)
         elif gtype == TYPE_POINTER:
             self.set_pointer(py_value)
-        elif gtype.is_a(TYPE_OBJECT):
-            self.set_object(py_value)
         elif gtype == TYPE_GTYPE:
             self.set_gtype(py_value)
         elif gtype == TYPE_VARIANT:
@@ -291,59 +262,41 @@ class Value(GObjectModule.Value):
         else:
             # Fall back to _gvalue_set which handles some more cases
             # like fundamentals for which a converter is registered
-            _gi._gvalue_set(self, py_value)
+            try:
+                _gi._gvalue_set(self, py_value)
+            except TypeError:
+                if gtype == TYPE_INVALID:
+                    raise TypeError("GObject.Value needs to be initialized first")
+                raise
 
     def get_value(self):
         gtype = self.__g_type
 
-        if gtype == TYPE_BOOLEAN:
-            return self.get_boolean()
-        elif gtype == TYPE_CHAR:
+        if gtype == TYPE_CHAR:
             return self.get_char()
         elif gtype == TYPE_UCHAR:
             return self.get_uchar()
-        elif gtype == TYPE_INT:
-            return self.get_int()
-        elif gtype == TYPE_UINT:
-            return self.get_uint()
-        elif gtype == TYPE_LONG:
-            return self.get_long()
-        elif gtype == TYPE_ULONG:
-            return self.get_ulong()
-        elif gtype == TYPE_INT64:
-            return self.get_int64()
-        elif gtype == TYPE_UINT64:
-            return self.get_uint64()
-        elif gtype == TYPE_FLOAT:
-            return self.get_float()
-        elif gtype == TYPE_DOUBLE:
-            return self.get_double()
-        elif gtype == TYPE_STRING:
-            return self.get_string()
-        elif gtype == TYPE_PYOBJECT:
-            return self.get_boxed()
         elif gtype == TYPE_PARAM:
             return self.get_param()
         elif gtype.is_a(TYPE_ENUM):
             return self.get_enum()
         elif gtype.is_a(TYPE_FLAGS):
             return self.get_flags()
-        elif gtype.is_a(TYPE_BOXED):
-            return self.get_boxed()
         elif gtype == TYPE_POINTER:
             return self.get_pointer()
-        elif gtype.is_a(TYPE_OBJECT):
-            return self.get_object()
         elif gtype == TYPE_GTYPE:
             return self.get_gtype()
         elif gtype == TYPE_VARIANT:
             # get_variant was missing annotations
             # https://gitlab.gnome.org/GNOME/glib/merge_requests/492
             return self.dup_variant()
-        elif gtype == _gi.TYPE_INVALID:
-            return None
         else:
-            return _gi._gvalue_get(self)
+            try:
+                return _gi._gvalue_get(self)
+            except TypeError:
+                if gtype == TYPE_INVALID:
+                    return None
+                raise
 
     def __repr__(self):
         return '<Value (%s) %s>' % (self.__g_type.name, self.get_value())
diff --git a/tests/test_overrides_gobject.py b/tests/test_overrides_gobject.py
index e62a27fd..7f20e81a 100644
--- a/tests/test_overrides_gobject.py
+++ b/tests/test_overrides_gobject.py
@@ -5,7 +5,7 @@ from __future__ import absolute_import
 import pytest
 
 from gi import PyGIDeprecationWarning
-from gi.repository import GObject, GLib
+from gi.repository import GObject, GLib, GIMarshallingTests
 
 from gi._compat import PY2
 from .helper import ignore_gi_deprecation_warnings
@@ -113,6 +113,74 @@ def test_value_ulong():
     with pytest.raises(OverflowError):
         v.set_value(-1)
 
+    with pytest.raises(TypeError):
+        v.set_value(object())
+
+    with pytest.raises(TypeError):
+        v.set_value(None)
+
+
+def test_value_float():
+    v = GObject.Value(GObject.TYPE_FLOAT)
+
+    for getter, setter in [(v.get_value, v.set_value),
+                           (v.get_float, v.set_float)]:
+
+        assert getter() == 0.0
+        setter(0)
+        assert getter() == 0
+
+        setter(GLib.MAXFLOAT)
+        assert getter() == GLib.MAXFLOAT
+
+        setter(GLib.MINFLOAT)
+        assert getter() == GLib.MINFLOAT
+
+        setter(-GLib.MAXFLOAT)
+        assert getter() == -GLib.MAXFLOAT
+
+        with pytest.raises(OverflowError):
+            setter(GLib.MAXFLOAT * 2)
+
+        with pytest.raises(OverflowError):
+            setter(-GLib.MAXFLOAT * 2)
+
+        with pytest.raises(TypeError):
+            setter(object())
+
+        with pytest.raises(TypeError):
+            setter(None)
+
+        with pytest.raises(TypeError):
+            setter(1j)
+
+        v.reset()
+
+
+def test_value_double():
+    v = GObject.Value(GObject.TYPE_DOUBLE)
+    assert v.get_value() == 0.0
+    v.set_value(0)
+    assert v.get_value() == 0
+
+    v.set_value(GLib.MAXDOUBLE)
+    assert v.get_value() == GLib.MAXDOUBLE
+
+    v.set_value(GLib.MINDOUBLE)
+    assert v.get_value() == GLib.MINDOUBLE
+
+    v.set_value(-GLib.MAXDOUBLE)
+    assert v.get_value() == -GLib.MAXDOUBLE
+
+    with pytest.raises(TypeError):
+        v.set_value(object())
+
+    with pytest.raises(TypeError):
+        v.set_value(None)
+
+    with pytest.raises(TypeError):
+        v.set_value(1j)
+
 
 def test_value_uint64():
     v = GObject.Value(GObject.TYPE_UINT64)
@@ -147,6 +215,12 @@ def test_value_int64():
     with pytest.raises(OverflowError):
         v.set_value(GLib.MININT64 - 1)
 
+    with pytest.raises(TypeError):
+        v.set_value(object())
+
+    with pytest.raises(TypeError):
+        v.set_value(None)
+
 
 def test_value_pointer():
     v = GObject.Value(GObject.TYPE_POINTER)
@@ -206,24 +280,29 @@ def test_value_param():
 
 def test_value_string():
     v = GObject.Value(GObject.TYPE_STRING)
-    assert v.get_value() is None
+    for getter, setter in [(v.get_value, v.set_value),
+                           (v.get_string, v.set_string)]:
 
-    if PY2:
-        v.set_value(b"bar")
-        assert v.get_value() == b"bar"
+        assert getter() is None
 
-        v.set_value(u"öäü")
-        assert v.get_value().decode("utf-8") == u"öäü"
-    else:
-        with pytest.raises(TypeError):
-            v.set_value(b"bar")
+        if PY2:
+            setter(b"bar")
+            assert getter() == b"bar"
 
-    v.set_value(u"quux")
-    assert v.get_value() == u"quux"
-    assert isinstance(v.get_value(), str)
+            setter(u"öäü")
+            assert getter().decode("utf-8") == u"öäü"
+        else:
+            with pytest.raises(TypeError):
+                setter(b"bar")
 
-    v.set_value(None)
-    assert v.get_value() is None
+        setter(u"quux")
+        assert getter() == u"quux"
+        assert isinstance(getter(), str)
+
+        setter(None)
+        assert getter() is None
+
+        v.reset()
 
 
 def test_value_pyobject():
@@ -284,20 +363,73 @@ def test_value_set_boxed_deprecate_non_boxed():
 
 def test_value_boolean():
     v = GObject.Value(GObject.TYPE_BOOLEAN)
-    assert v.get_value() is False
-    assert isinstance(v.get_value(), bool)
+    for getter, setter in [(v.get_value, v.set_value),
+                           (v.get_boolean, v.set_boolean)]:
+        assert getter() is False
+        assert isinstance(getter(), bool)
 
-    v.set_value(42)
-    assert v.get_value() is True
-    v.set_value(-1)
-    assert v.get_value() is True
-    v.set_value(0)
-    assert v.get_value() is False
+        setter(42)
+        assert getter() is True
+        setter(-1)
+        assert getter() is True
+        setter(0)
+        assert getter() is False
 
-    v.set_value([])
-    assert v.get_value() is False
-    v.set_value(["foo"])
-    assert v.get_value() is True
+        setter([])
+        assert getter() is False
+        setter(["foo"])
+        assert getter() is True
 
-    v.set_value(None)
-    assert v.get_value() is False
+        setter(None)
+        assert getter() is False
+        v.reset()
+
+
+def test_value_enum():
+    t = GIMarshallingTests.GEnum
+    v = GObject.Value(t)
+
+    for getter, setter in [(v.get_value, v.set_value),
+                           (v.get_enum, v.set_enum)]:
+        assert v.g_type == t.__gtype__
+        assert getter() == 0
+
+        setter(t.VALUE1)
+        assert getter() == t.VALUE1
+        # FIXME: we should try to return an enum type
+        assert type(getter()) is int
+
+        setter(2424242)
+        assert getter() == 2424242
+
+        setter(-1)
+        assert getter() == -1
+
+        with pytest.raises(TypeError):
+            setter(object())
+
+        with pytest.raises(TypeError):
+            setter(None)
+
+        v.reset()
+
+
+def test_value_object():
+    v = GObject.Value(GIMarshallingTests.Object)
+    assert v.g_type.is_a(GObject.TYPE_OBJECT)
+
+    for getter, setter in [(v.get_value, v.set_value),
+                           (v.get_object, v.set_object)]:
+        assert getter() is None
+
+        setter(None)
+        assert getter() is None
+
+        obj = GIMarshallingTests.Object()
+        setter(obj)
+        assert getter() is obj
+
+        with pytest.raises(TypeError):
+            setter(object())
+
+        v.reset()


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]