# -*- Mode: Python; py-indent-offset: 4 -*- # vim: tabstop=4 shiftwidth=4 expandtab import unittest import traceback import ctypes import warnings import sys import os import re import platform import gc import timeit import pytest from gi.repository import Regress as Everything from gi.repository import GObject from gi.repository import GLib from gi.repository import Gio try: from gi.repository import Gtk Gtk # pyflakes except: Gtk = None from .helper import capture_exceptions const_str = b'const \xe2\x99\xa5 utf8'.decode('UTF-8') noconst_str = 'non' + const_str class RawGList(ctypes.Structure): _fields_ = [('data', ctypes.c_void_p), ('next', ctypes.c_void_p), ('prev', ctypes.c_void_p)] @classmethod def from_wrapped(cls, obj): offset = sys.getsizeof(object()) # size of PyObject_HEAD return ctypes.POINTER(cls).from_address(id(obj) + offset) class TestInstanceTransfer(unittest.TestCase): def test_main(self): obj = Everything.TestObj() for _ in range(10): obj.instance_method_full() class TestEverything(unittest.TestCase): def test_bool(self): self.assertEqual(Everything.test_boolean(False), False) self.assertEqual(Everything.test_boolean(True), True) self.assertEqual(Everything.test_boolean('hello'), True) self.assertEqual(Everything.test_boolean(''), False) self.assertEqual(Everything.test_boolean_true(True), True) self.assertEqual(Everything.test_boolean_false(False), False) def test_int8(self): self.assertEqual(Everything.test_int8(GLib.MAXINT8), GLib.MAXINT8) self.assertEqual(Everything.test_int8(GLib.MININT8), GLib.MININT8) self.assertRaises(OverflowError, Everything.test_int8, GLib.MAXINT8 + 1) with pytest.raises( OverflowError, match="%s not in range %s to %s" % ( GLib.MAXINT8 + 1, GLib.MININT8, GLib.MAXINT8)): Everything.test_int8(GLib.MAXINT8 + 1) with pytest.raises( OverflowError, match="%s not in range %s to %s" % ( GLib.MAXUINT64 * 2, GLib.MININT8, GLib.MAXINT8)): Everything.test_int8(GLib.MAXUINT64 * 2) def test_uint8(self): self.assertEqual(Everything.test_uint8(GLib.MAXUINT8), GLib.MAXUINT8) self.assertEqual(Everything.test_uint8(0), 0) self.assertRaises(OverflowError, Everything.test_uint8, -1) self.assertRaises(OverflowError, Everything.test_uint8, GLib.MAXUINT8 + 1) with pytest.raises( OverflowError, match="%s not in range 0 to %s" % ( GLib.MAXUINT8 + 1, GLib.MAXUINT8)): Everything.test_uint8(GLib.MAXUINT8 + 1) with pytest.raises( OverflowError, match="%s not in range 0 to %s" % ( GLib.MAXUINT64 * 2, GLib.MAXUINT8)): Everything.test_uint8(GLib.MAXUINT64 * 2) def test_int16(self): self.assertEqual(Everything.test_int16(GLib.MAXINT16), GLib.MAXINT16) self.assertEqual(Everything.test_int16(GLib.MININT16), GLib.MININT16) with pytest.raises( OverflowError, match="32768 not in range -32768 to 32767"): Everything.test_int16(GLib.MAXINT16 + 1) with pytest.raises( OverflowError, match="36893488147419103230 not in range -32768 to 32767"): Everything.test_int16(GLib.MAXUINT64 * 2) def test_uint16(self): self.assertEqual(Everything.test_uint16(GLib.MAXUINT16), GLib.MAXUINT16) self.assertEqual(Everything.test_uint16(0), 0) self.assertRaises(OverflowError, Everything.test_uint16, -1) with pytest.raises( OverflowError, match="%s not in range 0 to %s" % ( GLib.MAXUINT16 + 1, GLib.MAXUINT16)): Everything.test_uint16(GLib.MAXUINT16 + 1) with pytest.raises( OverflowError, match="%s not in range 0 to %s" % ( GLib.MAXUINT64 * 2, GLib.MAXUINT16)): Everything.test_uint16(GLib.MAXUINT64 * 2) def test_int32(self): self.assertEqual(Everything.test_int32(GLib.MAXINT32), GLib.MAXINT32) self.assertEqual(Everything.test_int32(GLib.MININT32), GLib.MININT32) with pytest.raises( OverflowError, match="2147483648 not in range -2147483648 to 2147483647"): Everything.test_int32(GLib.MAXINT32 + 1) with pytest.raises( OverflowError, match="%s not in range -2147483648 to 2147483647" % ( GLib.MAXINT64 + 1,)): Everything.test_int32(GLib.MAXINT64 + 1) def test_uint32(self): self.assertEqual(Everything.test_uint32(GLib.MAXUINT32), GLib.MAXUINT32) self.assertEqual(Everything.test_uint32(0), 0) self.assertRaises(OverflowError, Everything.test_uint32, -1) with pytest.raises( OverflowError, match="%s not in range 0 to %s" % ( GLib.MAXUINT32 + 1, GLib.MAXUINT32)): Everything.test_uint32(GLib.MAXUINT32 + 1) with pytest.raises( OverflowError, match="%s not in range 0 to %s" % ( GLib.MAXUINT64 * 2, GLib.MAXUINT32)): Everything.test_uint32(GLib.MAXUINT64 * 2) def test_int64(self): self.assertEqual(Everything.test_int64(GLib.MAXINT64), GLib.MAXINT64) self.assertEqual(Everything.test_int64(GLib.MININT64), GLib.MININT64) with pytest.raises( OverflowError, match="%s not in range %s to %s" % ( GLib.MAXINT64 + 1, GLib.MININT64, GLib.MAXINT64)): Everything.test_int64(GLib.MAXINT64 + 1) with pytest.raises( OverflowError, match="%s not in range %s to %s" % ( GLib.MAXUINT64 * 2, GLib.MININT64, GLib.MAXINT64)): Everything.test_int64(GLib.MAXUINT64 * 2) def test_uint64(self): self.assertEqual(Everything.test_uint64(GLib.MAXUINT64), GLib.MAXUINT64) self.assertEqual(Everything.test_uint64(0), 0) self.assertRaises(OverflowError, Everything.test_uint64, -1) self.assertRaises(OverflowError, Everything.test_uint64, GLib.MAXUINT64 + 1) with pytest.raises( OverflowError, match="%s not in range 0 to %s" % ( GLib.MAXUINT64 + 1, GLib.MAXUINT64)): Everything.test_uint64(GLib.MAXUINT64 + 1) with pytest.raises( OverflowError, match="%s not in range 0 to %s" % ( GLib.MAXUINT64 * 2, GLib.MAXUINT64)): Everything.test_uint64(GLib.MAXUINT64 * 2) def test_int(self): self.assertEqual(Everything.test_int(GLib.MAXINT), GLib.MAXINT) self.assertEqual(Everything.test_int(GLib.MININT), GLib.MININT) with pytest.raises( OverflowError, match="%s not in range %s to %s" % ( GLib.MAXINT + 1, GLib.MININT, GLib.MAXINT)): Everything.test_int(GLib.MAXINT + 1) with pytest.raises( OverflowError, match="%s not in range %s to %s" % ( GLib.MAXUINT64 * 2, GLib.MININT, GLib.MAXINT)): Everything.test_int(GLib.MAXUINT64 * 2) def test_uint(self): self.assertEqual(Everything.test_uint(GLib.MAXUINT), GLib.MAXUINT) self.assertEqual(Everything.test_uint(0), 0) self.assertRaises(OverflowError, Everything.test_uint, -1) with pytest.raises( OverflowError, match="%s not in range 0 to %s" % ( GLib.MAXUINT + 1, GLib.MAXUINT)): Everything.test_uint(GLib.MAXUINT + 1) with pytest.raises( OverflowError, match="%s not in range 0 to %s" % ( GLib.MAXUINT64 * 2, GLib.MAXUINT)): Everything.test_uint(GLib.MAXUINT64 * 2) def test_short(self): self.assertEqual(Everything.test_short(GLib.MAXSHORT), GLib.MAXSHORT) self.assertEqual(Everything.test_short(GLib.MINSHORT), GLib.MINSHORT) with pytest.raises( OverflowError, match="%s not in range %s to %s" % ( GLib.MAXSHORT + 1, GLib.MINSHORT, GLib.MAXSHORT)): Everything.test_short(GLib.MAXSHORT + 1) with pytest.raises( OverflowError, match="%s not in range %s to %s" % ( GLib.MAXUINT64 * 2, GLib.MINSHORT, GLib.MAXSHORT)): Everything.test_short(GLib.MAXUINT64 * 2) def test_ushort(self): self.assertEqual(Everything.test_ushort(GLib.MAXUSHORT), GLib.MAXUSHORT) self.assertEqual(Everything.test_ushort(0), 0) self.assertRaises(OverflowError, Everything.test_ushort, -1) with pytest.raises( OverflowError, match="%s not in range 0 to %s" % ( GLib.MAXUSHORT + 1, GLib.MAXUSHORT)): Everything.test_ushort(GLib.MAXUSHORT + 1) with pytest.raises( OverflowError, match="%s not in range 0 to %s" % ( GLib.MAXUINT64 * 2, GLib.MAXUSHORT)): Everything.test_ushort(GLib.MAXUINT64 * 2) def test_long(self): self.assertEqual(Everything.test_long(GLib.MAXLONG), GLib.MAXLONG) self.assertEqual(Everything.test_long(GLib.MINLONG), GLib.MINLONG) self.assertRaises(OverflowError, Everything.test_long, GLib.MAXLONG + 1) with pytest.raises( OverflowError, match="%s not in range %s to %s" % ( GLib.MAXLONG + 1, GLib.MINLONG, GLib.MAXLONG)): Everything.test_long(GLib.MAXLONG + 1) with pytest.raises( OverflowError, match="%s not in range %s to %s" % ( GLib.MAXUINT64 * 2, GLib.MINLONG, GLib.MAXLONG)): Everything.test_long(GLib.MAXUINT64 * 2) def test_ulong(self): self.assertEqual(Everything.test_ulong(GLib.MAXULONG), GLib.MAXULONG) self.assertEqual(Everything.test_ulong(0), 0) self.assertRaises(OverflowError, Everything.test_ulong, -1) with pytest.raises( OverflowError, match="%s not in range 0 to %s" % ( GLib.MAXULONG + 1, GLib.MAXULONG)): Everything.test_ulong(GLib.MAXULONG + 1) with pytest.raises( OverflowError, match="%s not in range 0 to %s" % ( GLib.MAXUINT64 * 2, GLib.MAXULONG)): Everything.test_ulong(GLib.MAXUINT64 * 2) def test_ssize(self): self.assertEqual(Everything.test_ssize(GLib.MAXSSIZE), GLib.MAXSSIZE) self.assertEqual(Everything.test_ssize(GLib.MINSSIZE), GLib.MINSSIZE) self.assertRaises(OverflowError, Everything.test_ssize, GLib.MAXSSIZE + 1) with pytest.raises( OverflowError, match="%s not in range %s to %s" % ( GLib.MAXSSIZE + 1, GLib.MINSSIZE, GLib.MAXSSIZE)): Everything.test_ssize(GLib.MAXSSIZE + 1) with pytest.raises( OverflowError, match="%s not in range %s to %s" % ( GLib.MAXUINT64 * 2, GLib.MINSSIZE, GLib.MAXSSIZE)): Everything.test_ssize(GLib.MAXUINT64 * 2) def test_size(self): self.assertEqual(Everything.test_size(GLib.MAXSIZE), GLib.MAXSIZE) self.assertEqual(Everything.test_size(0), 0) self.assertRaises(OverflowError, Everything.test_size, -1) self.assertRaises(OverflowError, Everything.test_size, GLib.MAXSIZE + 1) with pytest.raises( OverflowError, match="%s not in range 0 to %s" % ( GLib.MAXSIZE + 1, GLib.MAXSIZE)): Everything.test_size(GLib.MAXSIZE + 1) with pytest.raises( OverflowError, match="%s not in range 0 to %s" % ( GLib.MAXUINT64 * 2, GLib.MAXSIZE)): Everything.test_size(GLib.MAXUINT64 * 2) def test_timet(self): self.assertEqual(Everything.test_timet(42), 42) self.assertRaises(OverflowError, Everything.test_timet, GLib.MAXUINT64 + 1) def test_unichar(self): self.assertEqual("c", Everything.test_unichar("c")) self.assertEqual(chr(sys.maxunicode), Everything.test_unichar(chr(sys.maxunicode))) self.assertEqual(u"♥", Everything.test_unichar(u"♥")) self.assertRaises(TypeError, Everything.test_unichar, "") self.assertRaises(TypeError, Everything.test_unichar, "morethanonechar") def test_float(self): self.assertEqual(Everything.test_float(GLib.MAXFLOAT), GLib.MAXFLOAT) self.assertEqual(Everything.test_float(GLib.MINFLOAT), GLib.MINFLOAT) self.assertRaises(OverflowError, Everything.test_float, GLib.MAXFLOAT * 2) with pytest.raises( OverflowError, match=re.escape("%s not in range %s to %s" % ( GLib.MAXFLOAT * 2, -GLib.MAXFLOAT, GLib.MAXFLOAT))): Everything.test_float(GLib.MAXFLOAT * 2) def test_double(self): self.assertEqual(Everything.test_double(GLib.MAXDOUBLE), GLib.MAXDOUBLE) self.assertEqual(Everything.test_double(GLib.MINDOUBLE), GLib.MINDOUBLE) (two, three) = Everything.test_multi_double_args(2.5) self.assertAlmostEqual(two, 5.0) self.assertAlmostEqual(three, 7.5) def test_value(self): self.assertEqual(Everything.test_int_value_arg(GLib.MAXINT), GLib.MAXINT) self.assertEqual(Everything.test_value_return(GLib.MAXINT), GLib.MAXINT) def test_variant(self): v = Everything.test_gvariant_i() self.assertEqual(v.get_type_string(), 'i') self.assertEqual(v.get_int32(), 1) v = Everything.test_gvariant_s() self.assertEqual(v.get_type_string(), 's') self.assertEqual(v.get_string(), 'one') v = Everything.test_gvariant_v() self.assertEqual(v.get_type_string(), 'v') vi = v.get_variant() self.assertEqual(vi.get_type_string(), 's') self.assertEqual(vi.get_string(), 'contents') v = Everything.test_gvariant_as() self.assertEqual(v.get_type_string(), 'as') self.assertEqual(v.get_strv(), ['one', 'two', 'three']) v = Everything.test_gvariant_asv() self.assertEqual(v.get_type_string(), 'a{sv}') self.assertEqual(v.lookup_value('nosuchkey', None), None) name = v.lookup_value('name', None) self.assertEqual(name.get_string(), 'foo') timeout = v.lookup_value('timeout', None) self.assertEqual(timeout.get_int32(), 10) def test_utf8_const_return(self): self.assertEqual(Everything.test_utf8_const_return(), const_str) def test_utf8_nonconst_return(self): self.assertEqual(Everything.test_utf8_nonconst_return(), noconst_str) def test_utf8_out(self): self.assertEqual(Everything.test_utf8_out(), noconst_str) def test_utf8_const_in(self): Everything.test_utf8_const_in(const_str) def test_utf8_inout(self): self.assertEqual(Everything.test_utf8_inout(const_str), noconst_str) def test_filename_return(self): if os.name != "nt": result = [os.fsdecode(b'\xc3\xa5\xc3\xa4\xc3\xb6'), '/etc/fstab'] else: result = ['åäö', '/etc/fstab'] self.assertEqual(Everything.test_filename_return(), result) def test_int_out_utf8(self): # returns g_utf8_strlen() in out argument self.assertEqual(Everything.test_int_out_utf8(''), 0) self.assertEqual(Everything.test_int_out_utf8('hello world'), 11) self.assertEqual(Everything.test_int_out_utf8('åäö'), 3) def test_utf8_out_out(self): self.assertEqual(Everything.test_utf8_out_out(), ('first', 'second')) def test_utf8_out_nonconst_return(self): self.assertEqual(Everything.test_utf8_out_nonconst_return(), ('first', 'second')) def test_enum(self): self.assertEqual(Everything.test_enum_param(Everything.TestEnum.VALUE1), 'value1') self.assertEqual(Everything.test_enum_param(Everything.TestEnum.VALUE3), 'value3') self.assertRaises(TypeError, Everything.test_enum_param, 'hello') # FIXME: ValueError: invalid enum value: 2147483648 @unittest.expectedFailure def test_enum_unsigned(self): self.assertEqual(Everything.test_unsigned_enum_param(Everything.TestEnumUnsigned.VALUE1), 'value1') self.assertEqual(Everything.test_unsigned_enum_param(Everything.TestEnumUnsigned.VALUE3), 'value3') self.assertRaises(TypeError, Everything.test_unsigned_enum_param, 'hello') def test_flags(self): result = Everything.global_get_flags_out() # assert that it's not an int self.assertEqual(type(result), Everything.TestFlags) self.assertEqual(result, Everything.TestFlags.FLAG1 | Everything.TestFlags.FLAG3) def test_floating(self): e = Everything.TestFloating() self.assertEqual(e.__grefcount__, 1) e = GObject.new(Everything.TestFloating) self.assertEqual(e.__grefcount__, 1) e = Everything.TestFloating.new() self.assertEqual(e.__grefcount__, 1) def test_caller_allocates(self): struct_a = Everything.TestStructA() struct_a.some_int = 10 struct_a.some_int8 = 21 struct_a.some_double = 3.14 struct_a.some_enum = Everything.TestEnum.VALUE3 struct_a_clone = struct_a.clone() self.assertTrue(struct_a != struct_a_clone) self.assertEqual(struct_a.some_int, struct_a_clone.some_int) self.assertEqual(struct_a.some_int8, struct_a_clone.some_int8) self.assertEqual(struct_a.some_double, struct_a_clone.some_double) self.assertEqual(struct_a.some_enum, struct_a_clone.some_enum) struct_b = Everything.TestStructB() struct_b.some_int8 = 8 struct_b.nested_a.some_int = 20 struct_b.nested_a.some_int8 = 12 struct_b.nested_a.some_double = 333.3333 struct_b.nested_a.some_enum = Everything.TestEnum.VALUE2 struct_b_clone = struct_b.clone() self.assertTrue(struct_b != struct_b_clone) self.assertEqual(struct_b.some_int8, struct_b_clone.some_int8) self.assertEqual(struct_b.nested_a.some_int, struct_b_clone.nested_a.some_int) self.assertEqual(struct_b.nested_a.some_int8, struct_b_clone.nested_a.some_int8) self.assertEqual(struct_b.nested_a.some_double, struct_b_clone.nested_a.some_double) self.assertEqual(struct_b.nested_a.some_enum, struct_b_clone.nested_a.some_enum) struct_a = Everything.test_struct_a_parse('ignored') self.assertEqual(struct_a.some_int, 23) def test_wrong_type_of_arguments(self): try: Everything.test_int8() except TypeError: (e_type, e) = sys.exc_info()[:2] self.assertEqual(e.args, ("Regress.test_int8() takes exactly 1 argument (0 given)",)) def test_gtypes(self): gchararray_gtype = GObject.type_from_name('gchararray') gtype = Everything.test_gtype(str) self.assertEqual(gchararray_gtype, gtype) gtype = Everything.test_gtype('gchararray') self.assertEqual(gchararray_gtype, gtype) gobject_gtype = GObject.GObject.__gtype__ gtype = Everything.test_gtype(GObject.GObject) self.assertEqual(gobject_gtype, gtype) gtype = Everything.test_gtype('GObject') self.assertEqual(gobject_gtype, gtype) self.assertRaises(TypeError, Everything.test_gtype, 'invalidgtype') class NotARegisteredClass(object): pass self.assertRaises(TypeError, Everything.test_gtype, NotARegisteredClass) class ARegisteredClass(GObject.GObject): __gtype_name__ = 'EverythingTestsARegisteredClass' gtype = Everything.test_gtype('EverythingTestsARegisteredClass') self.assertEqual(ARegisteredClass.__gtype__, gtype) gtype = Everything.test_gtype(ARegisteredClass) self.assertEqual(ARegisteredClass.__gtype__, gtype) self.assertRaises(TypeError, Everything.test_gtype, 'ARegisteredClass') def test_dir(self): attr_list = dir(Everything) # test that typelib attributes are listed self.assertTrue('TestStructA' in attr_list) # test that class attributes and methods are listed self.assertTrue('__class__' in attr_list) self.assertTrue('__dir__' in attr_list) self.assertTrue('__repr__' in attr_list) # test that instance members are listed self.assertTrue('_namespace' in attr_list) self.assertTrue('_version' in attr_list) # test that there are no duplicates returned self.assertEqual(len(attr_list), len(set(attr_list))) def test_array_int_in_empty(self): self.assertEqual(Everything.test_array_int_in([]), 0) def test_array_int_in(self): self.assertEqual(Everything.test_array_int_in([1, 5, -2]), 4) def test_array_int_out(self): self.assertEqual(Everything.test_array_int_out(), [0, 1, 2, 3, 4]) def test_array_int_full_out(self): self.assertEqual(Everything.test_array_int_full_out(), [0, 1, 2, 3, 4]) def test_array_int_none_out(self): self.assertEqual(Everything.test_array_int_none_out(), [1, 2, 3, 4, 5]) def test_array_int_inout(self): self.assertEqual(Everything.test_array_int_inout([1, 5, 42, -8]), [6, 43, -7]) def test_array_int_inout_empty(self): self.assertEqual(Everything.test_array_int_inout([]), []) def test_array_gint8_in(self): self.assertEqual(Everything.test_array_gint8_in(b'\x01\x03\x05'), 9) self.assertEqual(Everything.test_array_gint8_in([1, 3, 5, -50]), -41) def test_array_gint16_in(self): self.assertEqual(Everything.test_array_gint16_in([256, 257, -1000, 10000]), 9513) def test_array_gint32_in(self): self.assertEqual(Everything.test_array_gint32_in([30000, 1, -2]), 29999) def test_array_gint64_in(self): self.assertEqual(Everything.test_array_gint64_in([2 ** 33, 2 ** 34]), 2 ** 33 + 2 ** 34) def test_array_gtype_in(self): self.assertEqual(Everything.test_array_gtype_in( [GObject.TYPE_STRING, GObject.TYPE_UINT64, GObject.TYPE_VARIANT]), '[gchararray,guint64,GVariant,]') def test_array_fixed_size_int_in(self): # fixed length of 5 self.assertEqual(Everything.test_array_fixed_size_int_in([1, 2, -10, 5, 3]), 1) def test_array_fixed_size_int_in_error(self): self.assertRaises(ValueError, Everything.test_array_fixed_size_int_in, [1, 2, 3, 4]) self.assertRaises(ValueError, Everything.test_array_fixed_size_int_in, [1, 2, 3, 4, 5, 6]) def test_array_fixed_size_int_out(self): self.assertEqual(Everything.test_array_fixed_size_int_out(), [0, 1, 2, 3, 4]) def test_array_fixed_size_int_return(self): self.assertEqual(Everything.test_array_fixed_size_int_return(), [0, 1, 2, 3, 4]) def test_garray_container_return(self): # GPtrArray transfer container result = Everything.test_garray_container_return() self.assertEqual(result, ['regress']) result = None def test_garray_full_return(self): # GPtrArray transfer full result = Everything.test_garray_full_return() self.assertEqual(result, ['regress']) result = None def test_strv_out(self): self.assertEqual(Everything.test_strv_out(), ['thanks', 'for', 'all', 'the', 'fish']) def test_strv_out_c(self): self.assertEqual(Everything.test_strv_out_c(), ['thanks', 'for', 'all', 'the', 'fish']) def test_strv_out_container(self): self.assertEqual(Everything.test_strv_out_container(), ['1', '2', '3']) def test_strv_outarg(self): self.assertEqual(Everything.test_strv_outarg(), ['1', '2', '3']) def test_strv_in_gvalue(self): self.assertEqual(Everything.test_strv_in_gvalue(), ['one', 'two', 'three']) def test_strv_in(self): Everything.test_strv_in(['1', '2', '3']) def test_glist(self): self.assertEqual(Everything.test_glist_nothing_return(), ['1', '2', '3']) self.assertEqual(Everything.test_glist_nothing_return2(), ['1', '2', '3']) self.assertEqual(Everything.test_glist_container_return(), ['1', '2', '3']) self.assertEqual(Everything.test_glist_everything_return(), ['1', '2', '3']) Everything.test_glist_nothing_in(['1', '2', '3']) Everything.test_glist_nothing_in2(['1', '2', '3']) @unittest.skipUnless(hasattr(Everything, 'test_glist_gtype_container_in'), 'Requires newer version of GI') def test_glist_gtype(self): Everything.test_glist_gtype_container_in( [Everything.TestObj, Everything.TestSubObj]) def test_gslist(self): self.assertEqual(Everything.test_gslist_nothing_return(), ['1', '2', '3']) self.assertEqual(Everything.test_gslist_nothing_return2(), ['1', '2', '3']) self.assertEqual(Everything.test_gslist_container_return(), ['1', '2', '3']) self.assertEqual(Everything.test_gslist_everything_return(), ['1', '2', '3']) Everything.test_gslist_nothing_in(['1', '2', '3']) Everything.test_gslist_nothing_in2(['1', '2', '3']) def test_hash_return(self): expected = {'foo': 'bar', 'baz': 'bat', 'qux': 'quux'} self.assertEqual(Everything.test_ghash_null_return(), None) self.assertEqual(Everything.test_ghash_nothing_return(), expected) self.assertEqual(Everything.test_ghash_nothing_return(), expected) self.assertEqual(Everything.test_ghash_container_return(), expected) self.assertEqual(Everything.test_ghash_everything_return(), expected) result = Everything.test_ghash_gvalue_return() self.assertEqual(result['integer'], 12) self.assertEqual(result['boolean'], True) self.assertEqual(result['string'], 'some text') self.assertEqual(result['strings'], ['first', 'second', 'third']) self.assertEqual(result['flags'], Everything.TestFlags.FLAG1 | Everything.TestFlags.FLAG3) self.assertEqual(result['enum'], Everything.TestEnum.VALUE2) result = None # FIXME: CRITICAL **: Unsupported type ghash def disabled_test_hash_return_nested(self): self.assertEqual(Everything.test_ghash_nested_everything_return(), {}) self.assertEqual(Everything.test_ghash_nested_everything_return2(), {}) def test_hash_in(self): expected = {'foo': 'bar', 'baz': 'bat', 'qux': 'quux'} Everything.test_ghash_nothing_in(expected) Everything.test_ghash_nothing_in2(expected) def test_hash_in_with_typed_strv(self): class GStrv(list): __gtype__ = GObject.TYPE_STRV data = {'integer': 12, 'boolean': True, 'string': 'some text', 'strings': GStrv(['first', 'second', 'third']), 'flags': Everything.TestFlags.FLAG1 | Everything.TestFlags.FLAG3, 'enum': Everything.TestEnum.VALUE2, } Everything.test_ghash_gvalue_in(data) data = None def test_hash_in_with_gvalue_strv(self): data = {'integer': 12, 'boolean': True, 'string': 'some text', 'strings': GObject.Value(GObject.TYPE_STRV, ['first', 'second', 'third']), 'flags': Everything.TestFlags.FLAG1 | Everything.TestFlags.FLAG3, 'enum': Everything.TestEnum.VALUE2, } Everything.test_ghash_gvalue_in(data) data = None @unittest.skipIf(platform.python_implementation() == "PyPy", "CPython only") def test_struct_gpointer(self): glist = GLib.List() raw = RawGList.from_wrapped(glist) # Note that pointer fields use 0 for NULL in PyGObject and None in ctypes self.assertEqual(glist.data, 0) self.assertEqual(raw.contents.data, None) glist.data = 123 self.assertEqual(glist.data, 123) self.assertEqual(raw.contents.data, 123) glist.data = None self.assertEqual(glist.data, 0) self.assertEqual(raw.contents.data, None) # Setting to anything other than an int should raise self.assertRaises(TypeError, setattr, glist.data, 'nan') self.assertRaises(TypeError, setattr, glist.data, object()) self.assertRaises(TypeError, setattr, glist.data, 123.321) def test_struct_opaque(self): # we should get a sensible error message try: Everything.TestBoxedPrivate() self.fail('allocating disguised struct without default constructor unexpectedly succeeded') except TypeError: (e_type, e_value, e_tb) = sys.exc_info() self.assertEqual(e_type, TypeError) self.assertTrue('TestBoxedPrivate' in str(e_value), str(e_value)) self.assertTrue('constructor' in str(e_value), str(e_value)) tb = ''.join(traceback.format_exception(e_type, e_value, e_tb)) self.assertTrue('test_everything.py", line' in tb, tb) class TestNullableArgs(unittest.TestCase): def test_in_nullable_hash(self): Everything.test_ghash_null_in(None) def test_in_nullable_list(self): Everything.test_gslist_null_in(None) Everything.test_glist_null_in(None) Everything.test_gslist_null_in([]) Everything.test_glist_null_in([]) def test_in_nullable_array(self): Everything.test_array_int_null_in(None) Everything.test_array_int_null_in([]) def test_in_nullable_string(self): Everything.test_utf8_null_in(None) def test_in_nullable_object(self): Everything.func_obj_null_in(None) def test_out_nullable_hash(self): self.assertEqual(None, Everything.test_ghash_null_out()) def test_out_nullable_list(self): self.assertEqual([], Everything.test_gslist_null_out()) self.assertEqual([], Everything.test_glist_null_out()) def test_out_nullable_array(self): self.assertEqual([], Everything.test_array_int_null_out()) def test_out_nullable_string(self): self.assertEqual(None, Everything.test_utf8_null_out()) def test_out_nullable_object(self): self.assertEqual(None, Everything.TestObj.null_out()) class TestCallbacks(unittest.TestCase): called = False main_loop = GLib.MainLoop() def test_callback(self): TestCallbacks.called = False def callback(): TestCallbacks.called = True Everything.test_simple_callback(callback) self.assertTrue(TestCallbacks.called) def test_callback_exception(self): """ This test ensures that we get errors from callbacks correctly and in particular that we do not segv when callbacks fail """ def callback(): x = 1 / 0 self.fail('unexpected surviving zero divsion:' + str(x)) # note that we do NOT expect the ZeroDivisionError to be propagated # through from the callback, as it crosses the Python<->C boundary # twice. (See GNOME #616279) with capture_exceptions() as exc: Everything.test_simple_callback(callback) self.assertTrue(exc) self.assertEqual(exc[0].type, ZeroDivisionError) def test_double_callback_exception(self): """ This test ensures that we get errors from callbacks correctly and in particular that we do not segv when callbacks fail """ def badcallback(): x = 1 / 0 self.fail('unexpected surviving zero divsion:' + str(x)) def callback(): Everything.test_boolean(True) Everything.test_boolean(False) Everything.test_simple_callback(badcallback()) # note that we do NOT expect the ZeroDivisionError to be propagated # through from the callback, as it crosses the Python<->C boundary # twice. (See GNOME #616279) with capture_exceptions() as exc: Everything.test_simple_callback(callback) self.assertTrue(exc) self.assertEqual(exc[0].type, ZeroDivisionError) def test_return_value_callback(self): TestCallbacks.called = False def callback(): TestCallbacks.called = True return 44 self.assertEqual(Everything.test_callback(callback), 44) self.assertTrue(TestCallbacks.called) def test_callback_scope_async(self): TestCallbacks.called = False ud = 'Test Value 44' def callback(user_data): self.assertEqual(user_data, ud) TestCallbacks.called = True return 44 if hasattr(sys, "getrefcount"): ud_refcount = sys.getrefcount(ud) callback_refcount = sys.getrefcount(callback) self.assertEqual(Everything.test_callback_async(callback, ud), None) # Callback should not have run and the ref count is increased by 1 self.assertEqual(TestCallbacks.called, False) if hasattr(sys, "getrefcount"): self.assertEqual(sys.getrefcount(callback), callback_refcount + 1) self.assertEqual(sys.getrefcount(ud), ud_refcount + 1) # test_callback_thaw_async will run the callback previously supplied. # references should be auto decremented after this call. self.assertEqual(Everything.test_callback_thaw_async(), 44) self.assertTrue(TestCallbacks.called) # Make sure refcounts are returned to normal if hasattr(sys, "getrefcount"): self.assertEqual(sys.getrefcount(callback), callback_refcount) self.assertEqual(sys.getrefcount(ud), ud_refcount) def test_callback_scope_call_multi(self): # This tests a callback that gets called multiple times from a # single scope call in python. TestCallbacks.called = 0 def callback(): TestCallbacks.called += 1 return TestCallbacks.called if hasattr(sys, "getrefcount"): refcount = sys.getrefcount(callback) result = Everything.test_multi_callback(callback) # first callback should give 1, second 2, and the function sums them up self.assertEqual(result, 3) self.assertEqual(TestCallbacks.called, 2) if hasattr(sys, "getrefcount"): self.assertEqual(sys.getrefcount(callback), refcount) def test_callback_scope_call_array(self): # This tests a callback that gets called multiple times from a # single scope call in python with array arguments TestCallbacks.callargs = [] # FIXME: would be cleaner without the explicit length args: # def callback(one, two): def callback(one, one_length, two, two_length): TestCallbacks.callargs.append((one, two)) return len(TestCallbacks.callargs) if hasattr(sys, "getrefcount"): refcount = sys.getrefcount(callback) result = Everything.test_array_callback(callback) # first callback should give 1, second 2, and the function sums them up self.assertEqual(result, 3) self.assertEqual(TestCallbacks.callargs, [([-1, 0, 1, 2], ['one', 'two', 'three'])] * 2) if hasattr(sys, "getrefcount"): self.assertEqual(sys.getrefcount(callback), refcount) @unittest.skipUnless(hasattr(Everything, 'test_array_inout_callback'), 'Requires newer version of GI') def test_callback_scope_call_array_inout(self): # This tests a callback that gets called multiple times from a # single scope call in python with inout array arguments TestCallbacks.callargs = [] def callback(ints, ints_length): TestCallbacks.callargs.append(ints) return ints[1:], len(ints[1:]) if hasattr(sys, "getrefcount"): refcount = sys.getrefcount(callback) result = Everything.test_array_inout_callback(callback) self.assertEqual(TestCallbacks.callargs, [[-2, -1, 0, 1, 2], [-1, 0, 1, 2]]) # first callback should give 4, second 3 self.assertEqual(result, 3) if hasattr(sys, "getrefcount"): self.assertEqual(sys.getrefcount(callback), refcount) def test_callback_userdata(self): TestCallbacks.called = 0 def callback(userdata): self.assertEqual(userdata, "Test%d" % TestCallbacks.called) TestCallbacks.called += 1 return TestCallbacks.called for i in range(100): val = Everything.test_callback_user_data(callback, "Test%d" % i) self.assertEqual(val, i + 1) self.assertEqual(TestCallbacks.called, 100) def test_callback_userdata_no_user_data(self): TestCallbacks.called = 0 def callback(): TestCallbacks.called += 1 return TestCallbacks.called for i in range(100): val = Everything.test_callback_user_data(callback) self.assertEqual(val, i + 1) self.assertEqual(TestCallbacks.called, 100) def test_callback_userdata_varargs(self): TestCallbacks.called = 0 collected_user_data = [] def callback(a, b): collected_user_data.extend([a, b]) TestCallbacks.called += 1 return TestCallbacks.called for i in range(10): val = Everything.test_callback_user_data(callback, 1, 2) self.assertEqual(val, i + 1) self.assertEqual(TestCallbacks.called, 10) self.assertSequenceEqual(collected_user_data, [1, 2] * 10) def test_callback_userdata_as_kwarg_tuple(self): TestCallbacks.called = 0 collected_user_data = [] def callback(user_data): collected_user_data.extend(user_data) TestCallbacks.called += 1 return TestCallbacks.called for i in range(10): val = Everything.test_callback_user_data(callback, user_data=(1, 2)) self.assertEqual(val, i + 1) self.assertEqual(TestCallbacks.called, 10) self.assertSequenceEqual(collected_user_data, [1, 2] * 10) def test_callback_user_data_middle_none(self): cb_info = {} def callback(userdata): cb_info['called'] = True cb_info['userdata'] = userdata return 1 (y, z, q) = Everything.test_torture_signature_2( 42, callback, None, 'some string', 3) self.assertEqual(y, 42) self.assertEqual(z, 84) self.assertEqual(q, 14) self.assertTrue(cb_info['called']) self.assertEqual(cb_info['userdata'], None) def test_callback_user_data_middle_single(self): cb_info = {} def callback(userdata): cb_info['called'] = True cb_info['userdata'] = userdata return 1 (y, z, q) = Everything.test_torture_signature_2( 42, callback, 'User Data', 'some string', 3) self.assertEqual(y, 42) self.assertEqual(z, 84) self.assertEqual(q, 14) self.assertTrue(cb_info['called']) self.assertEqual(cb_info['userdata'], 'User Data') def test_callback_user_data_middle_tuple(self): cb_info = {} def callback(userdata): cb_info['called'] = True cb_info['userdata'] = userdata return 1 (y, z, q) = Everything.test_torture_signature_2( 42, callback, (-5, 'User Data'), 'some string', 3) self.assertEqual(y, 42) self.assertEqual(z, 84) self.assertEqual(q, 14) self.assertTrue(cb_info['called']) self.assertEqual(cb_info['userdata'], (-5, 'User Data')) def test_async_ready_callback(self): TestCallbacks.called = False TestCallbacks.main_loop = GLib.MainLoop() def callback(obj, result, user_data): TestCallbacks.main_loop.quit() TestCallbacks.called = True Everything.test_async_ready_callback(callback) TestCallbacks.main_loop.run() self.assertTrue(TestCallbacks.called) def test_callback_scope_notified_with_destroy(self): TestCallbacks.called = 0 ud = 'Test scope notified data 33' def callback(user_data): self.assertEqual(user_data, ud) TestCallbacks.called += 1 return 33 if hasattr(sys, "getrefcount"): value_refcount = sys.getrefcount(ud) callback_refcount = sys.getrefcount(callback) # Callback is immediately called. for i in range(100): res = Everything.test_callback_destroy_notify(callback, ud) self.assertEqual(res, 33) self.assertEqual(TestCallbacks.called, 100) if hasattr(sys, "getrefcount"): self.assertEqual(sys.getrefcount(callback), callback_refcount + 100) self.assertEqual(sys.getrefcount(ud), value_refcount + 100) # thaw will call the callback again, this time resources should be freed self.assertEqual(Everything.test_callback_thaw_notifications(), 33 * 100) self.assertEqual(TestCallbacks.called, 200) if hasattr(sys, "getrefcount"): self.assertEqual(sys.getrefcount(callback), callback_refcount) self.assertEqual(sys.getrefcount(ud), value_refcount) def test_callback_scope_notified_with_destroy_no_user_data(self): TestCallbacks.called = 0 def callback(user_data): self.assertEqual(user_data, None) TestCallbacks.called += 1 return 34 if hasattr(sys, "getrefcount"): callback_refcount = sys.getrefcount(callback) # Run with warning as exception with warnings.catch_warnings(record=True) as w: warnings.simplefilter("error") self.assertRaises(RuntimeWarning, Everything.test_callback_destroy_notify_no_user_data, callback) self.assertEqual(TestCallbacks.called, 0) if hasattr(sys, "getrefcount"): self.assertEqual(sys.getrefcount(callback), callback_refcount) # Run with warning as warning with warnings.catch_warnings(record=True) as w: # Cause all warnings to always be triggered. warnings.simplefilter("default") # Trigger a warning. res = Everything.test_callback_destroy_notify_no_user_data(callback) # Verify some things self.assertEqual(len(w), 1) self.assertTrue(issubclass(w[-1].category, RuntimeWarning)) self.assertTrue('Callables passed to' in str(w[-1].message)) self.assertEqual(res, 34) self.assertEqual(TestCallbacks.called, 1) if hasattr(sys, "getrefcount"): self.assertEqual(sys.getrefcount(callback), callback_refcount + 1) # thaw will call the callback again, # refcount will not go down without user_data parameter self.assertEqual(Everything.test_callback_thaw_notifications(), 34) self.assertEqual(TestCallbacks.called, 2) if hasattr(sys, "getrefcount"): self.assertEqual(sys.getrefcount(callback), callback_refcount + 1) def test_callback_in_methods(self): object_ = Everything.TestObj() def callback(): TestCallbacks.called = True return 42 TestCallbacks.called = False object_.instance_method_callback(callback) self.assertTrue(TestCallbacks.called) TestCallbacks.called = False Everything.TestObj.static_method_callback(callback) self.assertTrue(TestCallbacks.called) def callbackWithUserData(user_data): TestCallbacks.called += 1 return 42 TestCallbacks.called = 0 Everything.TestObj.new_callback(callbackWithUserData, None) self.assertEqual(TestCallbacks.called, 1) # Note: using "new_callback" adds the notification to the same global # list as Everything.test_callback_destroy_notify, so thaw the list # so we don't get confusion between tests. self.assertEqual(Everything.test_callback_thaw_notifications(), 42) self.assertEqual(TestCallbacks.called, 2) def test_callback_none(self): # make sure this doesn't assert or crash Everything.test_simple_callback(None) def test_callback_gerror(self): def callback(error): self.assertEqual(error.message, 'regression test error') self.assertTrue('g-io' in error.domain) self.assertEqual(error.code, Gio.IOErrorEnum.NOT_SUPPORTED) TestCallbacks.called = True TestCallbacks.called = False Everything.test_gerror_callback(callback) self.assertTrue(TestCallbacks.called) def test_callback_null_gerror(self): def callback(error): self.assertEqual(error, None) TestCallbacks.called = True TestCallbacks.called = False Everything.test_null_gerror_callback(callback) self.assertTrue(TestCallbacks.called) def test_callback_owned_gerror(self): def callback(error): self.assertEqual(error.message, 'regression test owned error') self.assertTrue('g-io' in error.domain) self.assertEqual(error.code, Gio.IOErrorEnum.PERMISSION_DENIED) TestCallbacks.called = True TestCallbacks.called = False Everything.test_owned_gerror_callback(callback) self.assertTrue(TestCallbacks.called) def test_callback_hashtable(self): def callback(data): self.assertEqual(data, mydict) mydict['new'] = 42 TestCallbacks.called = True mydict = {'foo': 1, 'bar': 2} TestCallbacks.called = False Everything.test_hash_table_callback(mydict, callback) self.assertTrue(TestCallbacks.called) self.assertEqual(mydict, {'foo': 1, 'bar': 2, 'new': 42}) class TestClosures(unittest.TestCase): def test_no_arg(self): def callback(): self.called = True return 42 self.called = False result = Everything.test_closure(callback) self.assertTrue(self.called) self.assertEqual(result, 42) def test_int_arg(self): def callback(num): self.called = True return num + 1 self.called = False result = Everything.test_closure_one_arg(callback, 42) self.assertTrue(self.called) self.assertEqual(result, 43) def test_variant(self): def callback(variant): self.called = True if variant is None: return None self.assertEqual(variant.get_type_string(), 'i') return GLib.Variant('i', variant.get_int32() + 1) self.called = False result = Everything.test_closure_variant(callback, GLib.Variant('i', 42)) self.assertTrue(self.called) self.assertEqual(result.get_type_string(), 'i') self.assertEqual(result.get_int32(), 43) self.called = False result = Everything.test_closure_variant(callback, None) self.assertTrue(self.called) self.assertEqual(result, None) self.called = False self.assertRaises(TypeError, Everything.test_closure_variant, callback, 'foo') self.assertFalse(self.called) def test_variant_wrong_return_type(self): def callback(variant): return 'no_variant' with capture_exceptions() as exc: # this does not directly raise an exception (see # https://bugzilla.gnome.org/show_bug.cgi?id=616279) result = Everything.test_closure_variant(callback, GLib.Variant('i', 42)) # ... but the result shouldn't be a string self.assertEqual(result, None) # and the error should be shown self.assertEqual(len(exc), 1) self.assertEqual(exc[0].type, TypeError) self.assertTrue('return value' in str(exc[0].value), exc[0].value) class TestBoxed(unittest.TestCase): def test_boxed(self): object_ = Everything.TestObj() self.assertEqual(object_.props.boxed, None) boxed = Everything.TestBoxed() boxed.some_int8 = 42 object_.props.boxed = boxed self.assertTrue(isinstance(object_.props.boxed, Everything.TestBoxed)) self.assertEqual(object_.props.boxed.some_int8, 42) def test_boxed_alternative_constructor(self): boxed = Everything.TestBoxed.new_alternative_constructor1(5) self.assertEqual(boxed.some_int8, 5) boxed = Everything.TestBoxed.new_alternative_constructor2(5, 3) self.assertEqual(boxed.some_int8, 8) boxed = Everything.TestBoxed.new_alternative_constructor3("-3") self.assertEqual(boxed.some_int8, -3) def test_boxed_equality(self): boxed42 = Everything.TestBoxed.new_alternative_constructor1(42) boxed5 = Everything.TestBoxed.new_alternative_constructor1(5) boxed42_2 = Everything.TestBoxed.new_alternative_constructor2(41, 1) self.assertFalse(boxed42.equals(boxed5)) self.assertTrue(boxed42.equals(boxed42_2)) self.assertTrue(boxed42_2.equals(boxed42)) self.assertTrue(boxed42.equals(boxed42)) def test_boxed_b_constructor(self): with warnings.catch_warnings(record=True) as warn: warnings.simplefilter('always') boxed = Everything.TestBoxedB(42, 47) self.assertTrue(issubclass(warn[0].category, DeprecationWarning)) self.assertEqual(boxed.some_int8, 0) self.assertEqual(boxed.some_long, 0) def test_boxed_c_equality(self): boxed = Everything.TestBoxedC() # TestBoxedC uses refcounting, so we know that # the pointer is the same when copied copy = boxed.copy() self.assertEqual(boxed, copy) self.assertNotEqual(id(boxed), id(copy)) def test_boxed_c_wrapper(self): wrapper = Everything.TestBoxedCWrapper() obj = wrapper.get() # TestBoxedC uses refcounting, so we know that # it should be 2 at this point: # - one owned by @wrapper # - another owned by @obj self.assertEqual(obj.refcount, 2) del wrapper gc.collect() gc.collect() self.assertEqual(obj.refcount, 1) def test_boxed_c_wrapper_copy(self): wrapper = Everything.TestBoxedCWrapper() wrapper_copy = wrapper.copy() obj = wrapper.get() # TestBoxedC uses refcounting, so we know that # it should be 3 at this point: # - one owned by @wrapper # - one owned by @wrapper_copy # - another owned by @obj self.assertEqual(obj.refcount, 3) del wrapper gc.collect() gc.collect() self.assertEqual(obj.refcount, 2) del wrapper_copy gc.collect() gc.collect() self.assertEqual(obj.refcount, 1) del obj gc.collect() gc.collect() def test_array_fixed_boxed_none_out(self): arr = Everything.test_array_fixed_boxed_none_out() assert len(arr) == 2 assert arr[0].refcount == 2 assert arr[1].refcount == 2 def test_glist_boxed_none_return(self): assert len(Everything.test_glist_boxed_none_return(0)) == 0 list_ = Everything.test_glist_boxed_none_return(2) assert len(list_) == 2 assert list_[0].refcount == 2 assert list_[1].refcount == 2 def test_glist_boxed_full_return(self): assert len(Everything.test_glist_boxed_full_return(0)) == 0 list_ = Everything.test_glist_boxed_full_return(2) assert len(list_) == 2 assert list_[0].refcount == 1 assert list_[1].refcount == 1 class TestTortureProfile(unittest.TestCase): def test_torture_profile(self): total_time = 0 print("") object_ = Everything.TestObj() sys.stdout.write("\ttorture test 1 (10000 iterations): ") start_time = timeit.default_timer() for i in range(10000): (y, z, q) = object_.torture_signature_0(5000, "Torture Test 1", 12345) end_time = timeit.default_timer() delta_time = end_time - start_time total_time += delta_time print("%f secs" % delta_time) sys.stdout.write("\ttorture test 2 (10000 iterations): ") start_time = timeit.default_timer() for i in range(10000): (y, z, q) = Everything.TestObj().torture_signature_0( 5000, "Torture Test 2", 12345) end_time = timeit.default_timer() delta_time = end_time - start_time total_time += delta_time print("%f secs" % delta_time) sys.stdout.write("\ttorture test 3 (10000 iterations): ") start_time = timeit.default_timer() for i in range(10000): try: (y, z, q) = object_.torture_signature_1( 5000, "Torture Test 3", 12345) except: pass end_time = timeit.default_timer() delta_time = end_time - start_time total_time += delta_time print("%f secs" % delta_time) sys.stdout.write("\ttorture test 4 (10000 iterations): ") def callback(userdata): return 0 userdata = [1, 2, 3, 4] start_time = timeit.default_timer() for i in range(10000): (y, z, q) = Everything.test_torture_signature_2( 5000, callback, userdata, "Torture Test 4", 12345) end_time = timeit.default_timer() delta_time = end_time - start_time total_time += delta_time print("%f secs" % delta_time) print("\t====") print("\tTotal: %f sec" % total_time) class TestAdvancedInterfaces(unittest.TestCase): def test_array_objs(self): obj1, obj2 = Everything.test_array_fixed_out_objects() self.assertTrue(isinstance(obj1, Everything.TestObj)) self.assertTrue(isinstance(obj2, Everything.TestObj)) self.assertNotEqual(obj1, obj2) def test_obj_skip_return_val(self): obj = Everything.TestObj() ret = obj.skip_return_val(50, 42.0, 60, 2, 3) self.assertEqual(len(ret), 3) self.assertEqual(ret[0], 51) self.assertEqual(ret[1], 61) self.assertEqual(ret[2], 32) def test_obj_skip_return_val_no_out(self): obj = Everything.TestObj() # raises an error for 0, succeeds for any other value self.assertRaises(GLib.GError, obj.skip_return_val_no_out, 0) ret = obj.skip_return_val_no_out(1) self.assertEqual(ret, None)