diff options
| author | Christoph Reiter <reiter.christoph@gmail.com> | 2019-01-19 14:21:56 +0100 |
|---|---|---|
| committer | Christoph Reiter <reiter.christoph@gmail.com> | 2019-01-19 14:37:31 +0100 |
| commit | 125e679722f4628ce20baacb179a3675ca0c0863 (patch) | |
| tree | ce08fab35df99caade0cde5366b73bc810f1a924 | |
| parent | b66e964ec1b27d5786d2e2276d18764df6a06e6c (diff) | |
| download | pygobject-125e679722f4628ce20baacb179a3675ca0c0863.tar.gz | |
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.
| -rw-r--r-- | gi/overrides/GObject.py | 93 | ||||
| -rw-r--r-- | 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() |
