Commit 125e6797 authored by Christoph Reiter's avatar Christoph Reiter 🐍

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.
parent b66e964e
......@@ -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())
......
......@@ -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()
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