release
[pygobject.git] / tests / test_properties.py
blobce035cd778d80e07ef0bacbf4f2510e8ab0c280c
1 # coding=utf-8
3 import os
4 import gc
5 import sys
6 import struct
7 import types
8 import unittest
9 import tempfile
11 from gi.repository import GObject
12 from gi.repository.GObject import ParamFlags, GType, new
13 from gi.repository.GObject import \
14 TYPE_INT, TYPE_UINT, TYPE_LONG, TYPE_ULONG, TYPE_INT64, \
15 TYPE_UINT64, TYPE_GTYPE, TYPE_INVALID, TYPE_NONE, TYPE_STRV, \
16 TYPE_INTERFACE, TYPE_CHAR, TYPE_UCHAR, TYPE_BOOLEAN, TYPE_FLOAT, \
17 TYPE_DOUBLE, TYPE_POINTER, TYPE_BOXED, TYPE_PARAM, TYPE_OBJECT, \
18 TYPE_STRING, TYPE_PYOBJECT, TYPE_VARIANT
20 from gi.repository.GLib import \
21 MININT, MAXINT, MAXUINT, MINLONG, MAXLONG, MAXULONG, \
22 MAXUINT64, MAXINT64, MININT64
24 from gi.repository import Gio
25 from gi.repository import GLib
26 from gi.repository import GIMarshallingTests
27 from gi.repository import Regress
28 from gi import _propertyhelper as propertyhelper
30 from compathelper import _long
31 from helper import capture_glib_warnings, capture_output
34 class PropertyObject(GObject.GObject):
35 normal = GObject.Property(type=str)
36 construct = GObject.Property(
37 type=str,
38 flags=ParamFlags.READABLE | ParamFlags.WRITABLE | ParamFlags.CONSTRUCT,
39 default='default')
41 construct_only = GObject.Property(
42 type=str,
43 flags=ParamFlags.READABLE | ParamFlags.WRITABLE | ParamFlags.CONSTRUCT_ONLY)
45 uint64 = GObject.Property(
46 type=TYPE_UINT64,
47 flags=ParamFlags.READABLE | ParamFlags.WRITABLE | ParamFlags.CONSTRUCT)
49 enum = GObject.Property(
50 type=Gio.SocketType, default=Gio.SocketType.STREAM)
52 boxed = GObject.Property(
53 type=GLib.Regex,
54 flags=ParamFlags.READABLE | ParamFlags.WRITABLE | ParamFlags.CONSTRUCT)
56 flags = GObject.Property(
57 type=GIMarshallingTests.Flags,
58 flags=ParamFlags.READABLE | ParamFlags.WRITABLE | ParamFlags.CONSTRUCT,
59 default=GIMarshallingTests.Flags.VALUE1)
61 gtype = GObject.Property(
62 type=TYPE_GTYPE,
63 flags=ParamFlags.READABLE | ParamFlags.WRITABLE | ParamFlags.CONSTRUCT)
65 strings = GObject.Property(
66 type=TYPE_STRV,
67 flags=ParamFlags.READABLE | ParamFlags.WRITABLE | ParamFlags.CONSTRUCT)
69 variant = GObject.Property(
70 type=TYPE_VARIANT,
71 flags=ParamFlags.READABLE | ParamFlags.WRITABLE | ParamFlags.CONSTRUCT)
73 variant_def = GObject.Property(
74 type=TYPE_VARIANT,
75 flags=ParamFlags.READABLE | ParamFlags.WRITABLE | ParamFlags.CONSTRUCT,
76 default=GLib.Variant('i', 42))
78 interface = GObject.Property(
79 type=Gio.File,
80 flags=ParamFlags.READABLE | ParamFlags.WRITABLE | ParamFlags.CONSTRUCT)
83 class PropertyInheritanceObject(Regress.TestObj):
84 # override property from the base class, with a different type
85 string = GObject.Property(type=int)
87 # a property entirely defined at the Python level
88 python_prop = GObject.Property(type=str)
91 class PropertySubClassObject(PropertyInheritanceObject):
92 # override property from the base class, with a different type
93 python_prop = GObject.Property(type=int)
96 class TestPropertyInheritanceObject(unittest.TestCase):
97 def test_override_gi_property(self):
98 self.assertNotEqual(Regress.TestObj.props.string.value_type,
99 PropertyInheritanceObject.props.string.value_type)
100 obj = PropertyInheritanceObject()
101 self.assertEqual(type(obj.props.string), int)
102 obj.props.string = 4
103 self.assertEqual(obj.props.string, 4)
105 def test_override_python_property(self):
106 obj = PropertySubClassObject()
107 self.assertEqual(type(obj.props.python_prop), int)
108 obj.props.python_prop = 5
109 self.assertEqual(obj.props.python_prop, 5)
112 class TestPropertyObject(unittest.TestCase):
113 def test_get_set(self):
114 obj = PropertyObject()
115 obj.props.normal = "value"
116 self.assertEqual(obj.props.normal, "value")
118 def test_hasattr_on_object(self):
119 obj = PropertyObject()
120 self.assertTrue(hasattr(obj.props, "normal"))
122 def test_hasattr_on_class(self):
123 self.assertTrue(hasattr(PropertyObject.props, "normal"))
125 def test_set_on_class(self):
126 def set(obj):
127 obj.props.normal = "foobar"
129 self.assertRaises(TypeError, set, PropertyObject)
131 def test_iteration(self):
132 for obj in (PropertyObject.props, PropertyObject().props):
133 names = []
134 for pspec in obj:
135 gtype = GType(pspec)
136 self.assertEqual(gtype.parent.name, 'GParam')
137 names.append(pspec.name)
139 names.sort()
140 self.assertEqual(names, ['boxed',
141 'construct',
142 'construct-only',
143 'enum',
144 'flags',
145 'gtype',
146 'interface',
147 'normal',
148 'strings',
149 'uint64',
150 'variant',
151 'variant-def'])
153 def test_normal(self):
154 obj = new(PropertyObject, normal="123")
155 self.assertEqual(obj.props.normal, "123")
156 obj.set_property('normal', '456')
157 self.assertEqual(obj.props.normal, "456")
158 obj.props.normal = '789'
159 self.assertEqual(obj.props.normal, "789")
161 def test_construct(self):
162 obj = new(PropertyObject, construct="123")
163 self.assertEqual(obj.props.construct, "123")
164 obj.set_property('construct', '456')
165 self.assertEqual(obj.props.construct, "456")
166 obj.props.construct = '789'
167 self.assertEqual(obj.props.construct, "789")
169 def test_utf8(self):
170 test_utf8 = "♥"
171 unicode_utf8 = u"♥"
172 obj = new(PropertyObject, construct_only=unicode_utf8)
173 self.assertEqual(obj.props.construct_only, test_utf8)
174 obj.set_property('construct', unicode_utf8)
175 self.assertEqual(obj.props.construct, test_utf8)
176 obj.props.normal = unicode_utf8
177 self.assertEqual(obj.props.normal, test_utf8)
179 def test_int_to_str(self):
180 obj = new(PropertyObject, construct_only=1)
181 self.assertEqual(obj.props.construct_only, '1')
182 obj.set_property('construct', '2')
183 self.assertEqual(obj.props.construct, '2')
184 obj.props.normal = 3
185 self.assertEqual(obj.props.normal, '3')
187 def test_construct_only(self):
188 obj = new(PropertyObject, construct_only="123")
189 self.assertEqual(obj.props.construct_only, "123")
190 self.assertRaises(TypeError,
191 setattr, obj.props, 'construct_only', '456')
192 self.assertRaises(TypeError,
193 obj.set_property, 'construct-only', '456')
195 def test_uint64(self):
196 obj = new(PropertyObject)
197 self.assertEqual(obj.props.uint64, 0)
198 obj.props.uint64 = _long(1)
199 self.assertEqual(obj.props.uint64, _long(1))
200 obj.props.uint64 = 1
201 self.assertEqual(obj.props.uint64, _long(1))
203 self.assertRaises((TypeError, OverflowError), obj.set_property, "uint64", _long(-1))
204 self.assertRaises((TypeError, OverflowError), obj.set_property, "uint64", -1)
206 def test_uint64_default_value(self):
207 try:
208 class TimeControl(GObject.GObject):
209 __gproperties__ = {
210 'time': (TYPE_UINT64, 'Time', 'Time',
211 _long(0), (1 << 64) - 1, _long(0),
212 ParamFlags.READABLE)
214 except OverflowError:
215 (etype, ex) = sys.exc_info()[2:]
216 self.fail(str(ex))
218 def test_enum(self):
219 obj = new(PropertyObject)
220 self.assertEqual(obj.props.enum, Gio.SocketType.STREAM)
221 self.assertEqual(obj.enum, Gio.SocketType.STREAM)
222 obj.enum = Gio.SocketType.DATAGRAM
223 self.assertEqual(obj.props.enum, Gio.SocketType.DATAGRAM)
224 self.assertEqual(obj.enum, Gio.SocketType.DATAGRAM)
225 obj.props.enum = Gio.SocketType.STREAM
226 self.assertEqual(obj.props.enum, Gio.SocketType.STREAM)
227 self.assertEqual(obj.enum, Gio.SocketType.STREAM)
228 obj.props.enum = 2
229 self.assertEqual(obj.props.enum, Gio.SocketType.DATAGRAM)
230 self.assertEqual(obj.enum, Gio.SocketType.DATAGRAM)
231 obj.enum = 1
232 self.assertEqual(obj.props.enum, Gio.SocketType.STREAM)
233 self.assertEqual(obj.enum, Gio.SocketType.STREAM)
235 self.assertRaises(TypeError, setattr, obj, 'enum', 'foo')
236 self.assertRaises(TypeError, setattr, obj, 'enum', object())
238 self.assertRaises(TypeError, GObject.Property, type=Gio.SocketType)
239 self.assertRaises(TypeError, GObject.Property, type=Gio.SocketType,
240 default=Gio.SocketProtocol.TCP)
241 self.assertRaises(TypeError, GObject.Property, type=Gio.SocketType,
242 default=object())
243 self.assertRaises(TypeError, GObject.Property, type=Gio.SocketType,
244 default=1)
246 def test_flags(self):
247 obj = new(PropertyObject)
248 self.assertEqual(obj.props.flags, GIMarshallingTests.Flags.VALUE1)
249 self.assertEqual(obj.flags, GIMarshallingTests.Flags.VALUE1)
251 obj.flags = GIMarshallingTests.Flags.VALUE2 | GIMarshallingTests.Flags.VALUE3
252 self.assertEqual(obj.props.flags, GIMarshallingTests.Flags.VALUE2 | GIMarshallingTests.Flags.VALUE3)
253 self.assertEqual(obj.flags, GIMarshallingTests.Flags.VALUE2 | GIMarshallingTests.Flags.VALUE3)
255 self.assertRaises(TypeError, setattr, obj, 'flags', 'foo')
256 self.assertRaises(TypeError, setattr, obj, 'flags', object())
257 self.assertRaises(TypeError, setattr, obj, 'flags', None)
259 self.assertRaises(TypeError, GObject.Property,
260 type=GIMarshallingTests.Flags, default='foo')
261 self.assertRaises(TypeError, GObject.Property,
262 type=GIMarshallingTests.Flags, default=object())
263 self.assertRaises(TypeError, GObject.Property,
264 type=GIMarshallingTests.Flags, default=None)
266 def test_gtype(self):
267 obj = new(PropertyObject)
269 self.assertEqual(obj.props.gtype, TYPE_NONE)
270 self.assertEqual(obj.gtype, TYPE_NONE)
272 obj.gtype = TYPE_UINT64
273 self.assertEqual(obj.props.gtype, TYPE_UINT64)
274 self.assertEqual(obj.gtype, TYPE_UINT64)
276 obj.gtype = TYPE_INVALID
277 self.assertEqual(obj.props.gtype, TYPE_INVALID)
278 self.assertEqual(obj.gtype, TYPE_INVALID)
280 # GType parameters do not support defaults in GLib
281 self.assertRaises(TypeError, GObject.Property, type=TYPE_GTYPE,
282 default=TYPE_INT)
284 # incompatible type
285 self.assertRaises(TypeError, setattr, obj, 'gtype', 'foo')
286 self.assertRaises(TypeError, setattr, obj, 'gtype', object())
288 self.assertRaises(TypeError, GObject.Property, type=TYPE_GTYPE,
289 default='foo')
290 self.assertRaises(TypeError, GObject.Property, type=TYPE_GTYPE,
291 default=object())
293 # set in constructor
294 obj = new(PropertyObject, gtype=TYPE_UINT)
295 self.assertEqual(obj.props.gtype, TYPE_UINT)
296 self.assertEqual(obj.gtype, TYPE_UINT)
298 def test_boxed(self):
299 obj = new(PropertyObject)
301 regex = GLib.Regex.new('[a-z]*', 0, 0)
302 obj.props.boxed = regex
303 self.assertEqual(obj.props.boxed.get_pattern(), '[a-z]*')
304 self.assertEqual(obj.boxed.get_pattern(), '[a-z]*')
306 self.assertRaises(TypeError, setattr, obj, 'boxed', 'foo')
307 self.assertRaises(TypeError, setattr, obj, 'boxed', object())
309 def test_strings(self):
310 obj = new(PropertyObject)
312 # Should work with actual GStrv objects as well as
313 # Python string lists
314 class GStrv(list):
315 __gtype__ = GObject.TYPE_STRV
317 self.assertEqual(obj.props.strings, GStrv([]))
318 self.assertEqual(obj.strings, GStrv([]))
319 self.assertEqual(obj.props.strings, [])
320 self.assertEqual(obj.strings, [])
322 obj.strings = ['hello', 'world']
323 self.assertEqual(obj.props.strings, ['hello', 'world'])
324 self.assertEqual(obj.strings, ['hello', 'world'])
326 obj.strings = GStrv(['hello', 'world'])
327 self.assertEqual(obj.props.strings, GStrv(['hello', 'world']))
328 self.assertEqual(obj.strings, GStrv(['hello', 'world']))
330 obj.strings = []
331 self.assertEqual(obj.strings, [])
332 obj.strings = GStrv([])
333 self.assertEqual(obj.strings, GStrv([]))
335 p = GObject.Property(type=TYPE_STRV, default=['hello', '1'])
336 self.assertEqual(p.default, ['hello', '1'])
337 self.assertEqual(p.type, TYPE_STRV)
338 p = GObject.Property(type=TYPE_STRV, default=GStrv(['hello', '1']))
339 self.assertEqual(p.default, ['hello', '1'])
340 self.assertEqual(p.type, TYPE_STRV)
342 # set in constructor
343 obj = new(PropertyObject, strings=['hello', 'world'])
344 self.assertEqual(obj.props.strings, ['hello', 'world'])
345 self.assertEqual(obj.strings, ['hello', 'world'])
347 # wrong types
348 self.assertRaises(TypeError, setattr, obj, 'strings', 1)
349 self.assertRaises(TypeError, setattr, obj, 'strings', 'foo')
350 self.assertRaises(TypeError, setattr, obj, 'strings', ['foo', 1])
352 self.assertRaises(TypeError, GObject.Property, type=TYPE_STRV,
353 default=1)
354 self.assertRaises(TypeError, GObject.Property, type=TYPE_STRV,
355 default='foo')
356 self.assertRaises(TypeError, GObject.Property, type=TYPE_STRV,
357 default=['hello', 1])
359 def test_variant(self):
360 obj = new(PropertyObject)
362 self.assertEqual(obj.props.variant, None)
363 self.assertEqual(obj.variant, None)
365 obj.variant = GLib.Variant('s', 'hello')
366 self.assertEqual(obj.variant.print_(True), "'hello'")
368 obj.variant = GLib.Variant('b', True)
369 self.assertEqual(obj.variant.print_(True), "true")
371 obj.props.variant = GLib.Variant('y', 2)
372 self.assertEqual(obj.variant.print_(True), "byte 0x02")
374 obj.variant = None
375 self.assertEqual(obj.variant, None)
377 # set in constructor
378 obj = new(PropertyObject, variant=GLib.Variant('u', 5))
379 self.assertEqual(obj.props.variant.print_(True), 'uint32 5')
381 GObject.Property(type=TYPE_VARIANT, default=GLib.Variant('i', 1))
383 # incompatible types
384 self.assertRaises(TypeError, setattr, obj, 'variant', 'foo')
385 self.assertRaises(TypeError, setattr, obj, 'variant', 42)
387 self.assertRaises(TypeError, GObject.Property, type=TYPE_VARIANT,
388 default='foo')
389 self.assertRaises(TypeError, GObject.Property, type=TYPE_VARIANT,
390 default=object())
392 def test_variant_default(self):
393 obj = new(PropertyObject)
395 self.assertEqual(obj.props.variant_def.print_(True), '42')
396 self.assertEqual(obj.variant_def.print_(True), '42')
398 obj.props.variant_def = GLib.Variant('y', 2)
399 self.assertEqual(obj.variant_def.print_(True), "byte 0x02")
401 # set in constructor
402 obj = new(PropertyObject, variant_def=GLib.Variant('u', 5))
403 self.assertEqual(obj.props.variant_def.print_(True), 'uint32 5')
405 def test_interface(self):
406 obj = new(PropertyObject)
408 path = os.path.join(tempfile.gettempdir(), "some", "path")
409 file = Gio.File.new_for_path(path)
410 obj.props.interface = file
411 self.assertEqual(obj.props.interface.get_path(), path)
412 self.assertEqual(obj.interface.get_path(), path)
414 self.assertRaises(TypeError, setattr, obj, 'interface', 'foo')
415 self.assertRaises(TypeError, setattr, obj, 'interface', object())
417 def test_range(self):
418 # kiwi code
419 def max(c):
420 return 2 ** ((8 * struct.calcsize(c)) - 1) - 1
422 def umax(c):
423 return 2 ** (8 * struct.calcsize(c)) - 1
425 maxint = max('i')
426 minint = -maxint - 1
427 maxuint = umax('I')
428 maxlong = max('l')
429 minlong = -maxlong - 1
430 maxulong = umax('L')
431 maxint64 = max('q')
432 minint64 = -maxint64 - 1
433 maxuint64 = umax('Q')
435 types_ = dict(int=(TYPE_INT, minint, maxint),
436 uint=(TYPE_UINT, 0, maxuint),
437 long=(TYPE_LONG, minlong, maxlong),
438 ulong=(TYPE_ULONG, 0, maxulong),
439 int64=(TYPE_INT64, minint64, maxint64),
440 uint64=(TYPE_UINT64, 0, maxuint64))
442 def build_gproperties(types_):
443 d = {}
444 for key, (gtype, min, max) in types_.items():
445 d[key] = (gtype, 'blurb', 'desc', min, max, 0,
446 ParamFlags.READABLE | ParamFlags.WRITABLE)
447 return d
449 class RangeCheck(GObject.GObject):
450 __gproperties__ = build_gproperties(types_)
452 def __init__(self):
453 self.values = {}
454 GObject.GObject.__init__(self)
456 def do_set_property(self, pspec, value):
457 self.values[pspec.name] = value
459 def do_get_property(self, pspec):
460 return self.values.get(pspec.name, pspec.default_value)
462 self.assertEqual(RangeCheck.props.int.minimum, minint)
463 self.assertEqual(RangeCheck.props.int.maximum, maxint)
464 self.assertEqual(RangeCheck.props.uint.minimum, 0)
465 self.assertEqual(RangeCheck.props.uint.maximum, maxuint)
466 self.assertEqual(RangeCheck.props.long.minimum, minlong)
467 self.assertEqual(RangeCheck.props.long.maximum, maxlong)
468 self.assertEqual(RangeCheck.props.ulong.minimum, 0)
469 self.assertEqual(RangeCheck.props.ulong.maximum, maxulong)
470 self.assertEqual(RangeCheck.props.int64.minimum, minint64)
471 self.assertEqual(RangeCheck.props.int64.maximum, maxint64)
472 self.assertEqual(RangeCheck.props.uint64.minimum, 0)
473 self.assertEqual(RangeCheck.props.uint64.maximum, maxuint64)
475 obj = RangeCheck()
476 for key, (gtype, min, max) in types_.items():
477 self.assertEqual(obj.get_property(key),
478 getattr(RangeCheck.props, key).default_value)
480 obj.set_property(key, min)
481 self.assertEqual(obj.get_property(key), min)
483 obj.set_property(key, max)
484 self.assertEqual(obj.get_property(key), max)
486 def test_multi(self):
487 obj = PropertyObject()
488 obj.set_properties(normal="foo",
489 uint64=7)
490 normal, uint64 = obj.get_properties("normal", "uint64")
491 self.assertEqual(normal, "foo")
492 self.assertEqual(uint64, 7)
495 class TestProperty(unittest.TestCase):
496 def test_simple(self):
497 class C(GObject.GObject):
498 str = GObject.Property(type=str)
499 int = GObject.Property(type=int)
500 float = GObject.Property(type=float)
501 long = GObject.Property(type=_long)
503 self.assertTrue(hasattr(C.props, 'str'))
504 self.assertTrue(hasattr(C.props, 'int'))
505 self.assertTrue(hasattr(C.props, 'float'))
506 self.assertTrue(hasattr(C.props, 'long'))
508 o = C()
509 self.assertEqual(o.str, '')
510 o.str = 'str'
511 self.assertEqual(o.str, 'str')
513 self.assertEqual(o.int, 0)
514 o.int = 1138
515 self.assertEqual(o.int, 1138)
517 self.assertEqual(o.float, 0.0)
518 o.float = 3.14
519 self.assertEqual(o.float, 3.14)
521 self.assertEqual(o.long, _long(0))
522 o.long = _long(100)
523 self.assertEqual(o.long, _long(100))
525 def test_custom_getter(self):
526 class C(GObject.GObject):
527 def get_prop(self):
528 return 'value'
529 prop = GObject.Property(getter=get_prop)
531 o = C()
532 self.assertEqual(o.prop, 'value')
533 self.assertRaises(TypeError, setattr, o, 'prop', 'xxx')
535 @unittest.expectedFailure # https://bugzilla.gnome.org/show_bug.cgi?id=575652
536 def test_getter_exception(self):
537 class C(GObject.Object):
538 @GObject.Property(type=int)
539 def prop(self):
540 raise ValueError('something bad happend')
542 o = C()
544 # silence exception printed to stderr
545 with capture_output():
546 with self.assertRaisesRegex(ValueError, 'something bad happend'):
547 o.prop
549 with self.assertRaisesRegex(ValueError, 'something bad happend'):
550 o.get_property('prop')
552 with self.assertRaisesRegex(ValueError, 'something bad happend'):
553 o.props.prop
555 def test_custom_setter(self):
556 class C(GObject.GObject):
557 def set_prop(self, value):
558 self._value = value
559 prop = GObject.Property(setter=set_prop)
561 def __init__(self):
562 self._value = None
563 GObject.GObject.__init__(self)
565 o = C()
566 self.assertEqual(o._value, None)
567 o.prop = 'bar'
568 self.assertEqual(o._value, 'bar')
569 self.assertRaises(TypeError, getattr, o, 'prop')
571 def test_decorator_default(self):
572 class C(GObject.GObject):
573 _value = 'value'
575 @GObject.Property
576 def value(self):
577 return self._value
579 @value.setter
580 def value_setter(self, value):
581 self._value = value
583 o = C()
584 self.assertEqual(o.value, 'value')
585 o.value = 'blah'
586 self.assertEqual(o.value, 'blah')
587 self.assertEqual(o.props.value, 'blah')
589 def test_decorator_private_setter(self):
590 class C(GObject.GObject):
591 _value = 'value'
593 @GObject.Property
594 def value(self):
595 return self._value
597 @value.setter
598 def _set_value(self, value):
599 self._value = value
601 o = C()
602 self.assertEqual(o.value, 'value')
603 o.value = 'blah'
604 self.assertEqual(o.value, 'blah')
605 self.assertEqual(o.props.value, 'blah')
607 def test_decorator_with_call(self):
608 class C(GObject.GObject):
609 _value = 1
611 @GObject.Property(type=int, default=1, minimum=1, maximum=10)
612 def typedValue(self):
613 return self._value
615 @typedValue.setter
616 def typedValue_setter(self, value):
617 self._value = value
619 o = C()
620 self.assertEqual(o.typedValue, 1)
621 o.typedValue = 5
622 self.assertEqual(o.typedValue, 5)
623 self.assertEqual(o.props.typedValue, 5)
625 def test_errors(self):
626 self.assertRaises(TypeError, GObject.Property, type='str')
627 self.assertRaises(TypeError, GObject.Property, nick=False)
628 self.assertRaises(TypeError, GObject.Property, blurb=False)
629 # this never fail while bool is a subclass of int
630 # >>> bool.__bases__
631 # (<type 'int'>,)
632 # self.assertRaises(TypeError, GObject.Property, type=bool, default=0)
633 self.assertRaises(TypeError, GObject.Property, type=bool, default='ciao mamma')
634 self.assertRaises(TypeError, GObject.Property, type=bool)
635 self.assertRaises(TypeError, GObject.Property, type=object, default=0)
636 self.assertRaises(TypeError, GObject.Property, type=complex)
638 def test_defaults(self):
639 GObject.Property(type=bool, default=True)
640 GObject.Property(type=bool, default=False)
642 def test_name_with_underscore(self):
643 class C(GObject.GObject):
644 prop_name = GObject.Property(type=int)
645 o = C()
646 o.prop_name = 10
647 self.assertEqual(o.prop_name, 10)
649 def test_range(self):
650 types_ = [
651 (TYPE_INT, MININT, MAXINT),
652 (TYPE_UINT, 0, MAXUINT),
653 (TYPE_LONG, MINLONG, MAXLONG),
654 (TYPE_ULONG, 0, MAXULONG),
655 (TYPE_INT64, MININT64, MAXINT64),
656 (TYPE_UINT64, 0, MAXUINT64),
659 for gtype, min, max in types_:
660 # Normal, everything is alright
661 prop = GObject.Property(type=gtype, minimum=min, maximum=max)
662 subtype = type('', (GObject.GObject,), dict(prop=prop))
663 self.assertEqual(subtype.props.prop.minimum, min)
664 self.assertEqual(subtype.props.prop.maximum, max)
666 # Lower than minimum
667 self.assertRaises(TypeError,
668 GObject.Property, type=gtype, minimum=min - 1,
669 maximum=max)
671 # Higher than maximum
672 self.assertRaises(TypeError,
673 GObject.Property, type=gtype, minimum=min,
674 maximum=max + 1)
676 def test_min_max(self):
677 class C(GObject.GObject):
678 prop_int = GObject.Property(type=int, minimum=1, maximum=100, default=1)
679 prop_float = GObject.Property(type=float, minimum=0.1, maximum=10.5, default=1.1)
681 def __init__(self):
682 GObject.GObject.__init__(self)
684 # we test known-bad values here which cause Gtk-WARNING logs.
685 # Explicitly allow these for this test.
686 with capture_glib_warnings(allow_warnings=True):
687 o = C()
688 self.assertEqual(o.prop_int, 1)
690 o.prop_int = 5
691 self.assertEqual(o.prop_int, 5)
693 o.prop_int = 0
694 self.assertEqual(o.prop_int, 5)
696 o.prop_int = 101
697 self.assertEqual(o.prop_int, 5)
699 self.assertEqual(o.prop_float, 1.1)
701 o.prop_float = 7.75
702 self.assertEqual(o.prop_float, 7.75)
704 o.prop_float = 0.09
705 self.assertEqual(o.prop_float, 7.75)
707 o.prop_float = 10.51
708 self.assertEqual(o.prop_float, 7.75)
710 def test_multiple_instances(self):
711 class C(GObject.GObject):
712 prop = GObject.Property(type=str, default='default')
714 o1 = C()
715 o2 = C()
716 self.assertEqual(o1.prop, 'default')
717 self.assertEqual(o2.prop, 'default')
718 o1.prop = 'value'
719 self.assertEqual(o1.prop, 'value')
720 self.assertEqual(o2.prop, 'default')
722 def test_object_property(self):
723 class PropertyObject(GObject.GObject):
724 obj = GObject.Property(type=GObject.GObject)
726 pobj1 = PropertyObject()
727 obj1_hash = hash(pobj1)
728 pobj2 = PropertyObject()
730 pobj2.obj = pobj1
731 del pobj1
732 pobj1 = pobj2.obj
733 self.assertEqual(hash(pobj1), obj1_hash)
735 def test_object_subclass_property(self):
736 class ObjectSubclass(GObject.GObject):
737 __gtype_name__ = 'ObjectSubclass'
739 class PropertyObjectSubclass(GObject.GObject):
740 obj = GObject.Property(type=ObjectSubclass)
742 PropertyObjectSubclass(obj=ObjectSubclass())
744 def test_property_subclass(self):
745 # test for #470718
746 class A(GObject.GObject):
747 prop1 = GObject.Property(type=int)
749 class B(A):
750 prop2 = GObject.Property(type=int)
752 b = B()
753 b.prop2 = 10
754 self.assertEqual(b.prop2, 10)
755 b.prop1 = 20
756 self.assertEqual(b.prop1, 20)
758 def test_property_subclass_c(self):
759 class A(Regress.TestSubObj):
760 prop1 = GObject.Property(type=int)
762 a = A()
763 a.prop1 = 10
764 self.assertEqual(a.prop1, 10)
766 # also has parent properties
767 a.props.int = 20
768 self.assertEqual(a.props.int, 20)
770 # Some of which are unusable without introspection
771 a.props.list = ("str1", "str2")
772 self.assertEqual(a.props.list, ["str1", "str2"])
774 a.set_property("list", ("str3", "str4"))
775 self.assertEqual(a.props.list, ["str3", "str4"])
777 def test_property_subclass_custom_setter(self):
778 # test for #523352
779 class A(GObject.GObject):
780 def get_first(self):
781 return 'first'
782 first = GObject.Property(type=str, getter=get_first)
784 class B(A):
785 def get_second(self):
786 return 'second'
787 second = GObject.Property(type=str, getter=get_second)
789 a = A()
790 self.assertEqual(a.first, 'first')
791 self.assertRaises(TypeError, setattr, a, 'first', 'foo')
793 b = B()
794 self.assertEqual(b.first, 'first')
795 self.assertRaises(TypeError, setattr, b, 'first', 'foo')
796 self.assertEqual(b.second, 'second')
797 self.assertRaises(TypeError, setattr, b, 'second', 'foo')
799 def test_property_subclass_custom_setter_error(self):
800 try:
801 class A(GObject.GObject):
802 def get_first(self):
803 return 'first'
804 first = GObject.Property(type=str, getter=get_first)
806 def do_get_property(self, pspec):
807 pass
808 except TypeError:
809 pass
810 else:
811 raise AssertionError
813 # Bug 587637.
815 def test_float_min(self):
816 GObject.Property(type=float, minimum=-1)
817 GObject.Property(type=GObject.TYPE_FLOAT, minimum=-1)
818 GObject.Property(type=GObject.TYPE_DOUBLE, minimum=-1)
820 # Bug 644039
822 def test_reference_count(self):
823 # We can check directly if an object gets finalized, so we will
824 # observe it indirectly through the refcount of a member object.
826 # We create our dummy object and store its current refcount
827 o = object()
828 rc = sys.getrefcount(o)
830 # We add our object as a member to our newly created object we
831 # want to observe. Its refcount is increased by one.
832 t = PropertyObject(normal="test")
833 t.o = o
834 self.assertEqual(sys.getrefcount(o), rc + 1)
836 # Now we want to ensure we do not leak any references to our
837 # object with properties. If no ref is leaked, then when deleting
838 # the local reference to this object, its reference count shoud
839 # drop to zero, and our dummy object should loose one reference.
840 del t
841 self.assertEqual(sys.getrefcount(o), rc)
843 def test_doc_strings(self):
844 class C(GObject.GObject):
845 foo_blurbed = GObject.Property(type=int, blurb='foo_blurbed doc string')
847 @GObject.Property
848 def foo_getter(self):
849 """foo_getter doc string"""
850 return 0
852 self.assertEqual(C.foo_blurbed.blurb, 'foo_blurbed doc string')
853 self.assertEqual(C.foo_blurbed.__doc__, 'foo_blurbed doc string')
855 self.assertEqual(C.foo_getter.blurb, 'foo_getter doc string')
856 self.assertEqual(C.foo_getter.__doc__, 'foo_getter doc string')
858 def test_python_to_glib_type_mapping(self):
859 tester = GObject.Property()
860 self.assertEqual(tester._type_from_python(int), GObject.TYPE_INT)
861 if sys.version_info < (3, 0):
862 self.assertEqual(tester._type_from_python(long), GObject.TYPE_LONG)
863 self.assertEqual(tester._type_from_python(bool), GObject.TYPE_BOOLEAN)
864 self.assertEqual(tester._type_from_python(float), GObject.TYPE_DOUBLE)
865 self.assertEqual(tester._type_from_python(str), GObject.TYPE_STRING)
866 self.assertEqual(tester._type_from_python(object), GObject.TYPE_PYOBJECT)
868 self.assertEqual(tester._type_from_python(GObject.GObject), GObject.GObject.__gtype__)
869 self.assertEqual(tester._type_from_python(GObject.GEnum), GObject.GEnum.__gtype__)
870 self.assertEqual(tester._type_from_python(GObject.GFlags), GObject.GFlags.__gtype__)
871 self.assertEqual(tester._type_from_python(GObject.GBoxed), GObject.GBoxed.__gtype__)
872 self.assertEqual(tester._type_from_python(GObject.GInterface), GObject.GInterface.__gtype__)
874 for type_ in [TYPE_NONE, TYPE_INTERFACE, TYPE_CHAR, TYPE_UCHAR,
875 TYPE_INT, TYPE_UINT, TYPE_BOOLEAN, TYPE_LONG,
876 TYPE_ULONG, TYPE_INT64, TYPE_UINT64,
877 TYPE_FLOAT, TYPE_DOUBLE, TYPE_POINTER,
878 TYPE_BOXED, TYPE_PARAM, TYPE_OBJECT, TYPE_STRING,
879 TYPE_PYOBJECT, TYPE_GTYPE, TYPE_STRV]:
880 self.assertEqual(tester._type_from_python(type_), type_)
882 self.assertRaises(TypeError, tester._type_from_python, types.CodeType)
885 class TestInstallProperties(unittest.TestCase):
886 # These tests only test how signalhelper.install_signals works
887 # with the __gsignals__ dict and therefore does not need to use
888 # GObject as a base class because that would automatically call
889 # install_signals within the meta-class.
890 class Base(object):
891 __gproperties__ = {'test': (0, '', '', 0, 0, 0, 0)}
893 class Sub1(Base):
894 pass
896 class Sub2(Base):
897 @GObject.Property(type=int)
898 def sub2test(self):
899 return 123
901 class ClassWithPropertyAndGetterVFunc(object):
902 @GObject.Property(type=int)
903 def sub2test(self):
904 return 123
906 def do_get_property(self, name):
907 return 321
909 class ClassWithPropertyRedefined(object):
910 __gproperties__ = {'test': (0, '', '', 0, 0, 0, 0)}
911 test = GObject.Property(type=int)
913 def setUp(self):
914 self.assertEqual(len(self.Base.__gproperties__), 1)
915 propertyhelper.install_properties(self.Base)
916 self.assertEqual(len(self.Base.__gproperties__), 1)
918 def test_subclass_without_properties_is_not_modified(self):
919 self.assertFalse('__gproperties__' in self.Sub1.__dict__)
920 propertyhelper.install_properties(self.Sub1)
921 self.assertFalse('__gproperties__' in self.Sub1.__dict__)
923 def test_subclass_with_decorator_gets_gproperties_dict(self):
924 # Sub2 has Property instances but will not have a __gproperties__
925 # until install_properties is called
926 self.assertFalse('__gproperties__' in self.Sub2.__dict__)
927 self.assertFalse('do_get_property' in self.Sub2.__dict__)
928 self.assertFalse('do_set_property' in self.Sub2.__dict__)
930 propertyhelper.install_properties(self.Sub2)
931 self.assertTrue('__gproperties__' in self.Sub2.__dict__)
932 self.assertEqual(len(self.Base.__gproperties__), 1)
933 self.assertEqual(len(self.Sub2.__gproperties__), 1)
934 self.assertTrue('sub2test' in self.Sub2.__gproperties__)
936 # get/set vfuncs should have been added
937 self.assertTrue('do_get_property' in self.Sub2.__dict__)
938 self.assertTrue('do_set_property' in self.Sub2.__dict__)
940 def test_object_with_property_and_do_get_property_vfunc_raises(self):
941 self.assertRaises(TypeError, propertyhelper.install_properties,
942 self.ClassWithPropertyAndGetterVFunc)
944 def test_same_name_property_definitions_raises(self):
945 self.assertRaises(ValueError, propertyhelper.install_properties,
946 self.ClassWithPropertyRedefined)
949 class CPropertiesTestBase(object):
950 # Tests for properties implemented in C not Python.
952 def setUp(self):
953 self.obj = GIMarshallingTests.PropertiesObject()
955 def get_prop(self, obj, name):
956 raise NotImplementedError
958 def set_prop(self, obj, name, value):
959 raise NotImplementedError
961 # https://bugzilla.gnome.org/show_bug.cgi?id=780652
962 @unittest.skipUnless(
963 "some_flags" in dir(GIMarshallingTests.PropertiesObject.props),
964 "tool old gi")
965 def test_flags(self):
966 self.assertEqual(
967 self.get_prop(self.obj, 'some-flags'),
968 GIMarshallingTests.Flags.VALUE1)
969 self.set_prop(self.obj, 'some-flags', GIMarshallingTests.Flags.VALUE2)
970 self.assertEqual(self.get_prop(self.obj, 'some-flags'),
971 GIMarshallingTests.Flags.VALUE2)
973 obj = GIMarshallingTests.PropertiesObject(
974 some_flags=GIMarshallingTests.Flags.VALUE3)
975 self.assertEqual(self.get_prop(obj, 'some-flags'),
976 GIMarshallingTests.Flags.VALUE3)
978 # https://bugzilla.gnome.org/show_bug.cgi?id=780652
979 @unittest.skipUnless(
980 "some_enum" in dir(GIMarshallingTests.PropertiesObject.props),
981 "tool old gi")
982 def test_enum(self):
983 self.assertEqual(
984 self.get_prop(self.obj, 'some-enum'),
985 GIMarshallingTests.GEnum.VALUE1)
986 self.set_prop(self.obj, 'some-enum', GIMarshallingTests.GEnum.VALUE2)
987 self.assertEqual(self.get_prop(self.obj, 'some-enum'),
988 GIMarshallingTests.GEnum.VALUE2)
990 obj = GIMarshallingTests.PropertiesObject(
991 some_enum=GIMarshallingTests.GEnum.VALUE3)
992 self.assertEqual(self.get_prop(obj, 'some-enum'),
993 GIMarshallingTests.GEnum.VALUE3)
995 def test_boolean(self):
996 self.assertEqual(self.get_prop(self.obj, 'some-boolean'), False)
997 self.set_prop(self.obj, 'some-boolean', True)
998 self.assertEqual(self.get_prop(self.obj, 'some-boolean'), True)
1000 obj = GIMarshallingTests.PropertiesObject(some_boolean=True)
1001 self.assertEqual(self.get_prop(obj, 'some-boolean'), True)
1003 def test_char(self):
1004 self.assertEqual(self.get_prop(self.obj, 'some-char'), 0)
1005 self.set_prop(self.obj, 'some-char', GLib.MAXINT8)
1006 self.assertEqual(self.get_prop(self.obj, 'some-char'), GLib.MAXINT8)
1008 obj = GIMarshallingTests.PropertiesObject(some_char=-42)
1009 self.assertEqual(self.get_prop(obj, 'some-char'), -42)
1011 def test_uchar(self):
1012 self.assertEqual(self.get_prop(self.obj, 'some-uchar'), 0)
1013 self.set_prop(self.obj, 'some-uchar', GLib.MAXUINT8)
1014 self.assertEqual(self.get_prop(self.obj, 'some-uchar'), GLib.MAXUINT8)
1016 obj = GIMarshallingTests.PropertiesObject(some_uchar=42)
1017 self.assertEqual(self.get_prop(obj, 'some-uchar'), 42)
1019 def test_int(self):
1020 self.assertEqual(self.get_prop(self.obj, 'some_int'), 0)
1021 self.set_prop(self.obj, 'some-int', GLib.MAXINT)
1022 self.assertEqual(self.get_prop(self.obj, 'some_int'), GLib.MAXINT)
1024 obj = GIMarshallingTests.PropertiesObject(some_int=-42)
1025 self.assertEqual(self.get_prop(obj, 'some-int'), -42)
1027 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-int', 'foo')
1028 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-int', None)
1030 self.assertEqual(self.get_prop(obj, 'some-int'), -42)
1032 def test_uint(self):
1033 self.assertEqual(self.get_prop(self.obj, 'some_uint'), 0)
1034 self.set_prop(self.obj, 'some-uint', GLib.MAXUINT)
1035 self.assertEqual(self.get_prop(self.obj, 'some_uint'), GLib.MAXUINT)
1037 obj = GIMarshallingTests.PropertiesObject(some_uint=42)
1038 self.assertEqual(self.get_prop(obj, 'some-uint'), 42)
1040 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-uint', 'foo')
1041 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-uint', None)
1043 self.assertEqual(self.get_prop(obj, 'some-uint'), 42)
1045 def test_long(self):
1046 self.assertEqual(self.get_prop(self.obj, 'some_long'), 0)
1047 self.set_prop(self.obj, 'some-long', GLib.MAXLONG)
1048 self.assertEqual(self.get_prop(self.obj, 'some_long'), GLib.MAXLONG)
1050 obj = GIMarshallingTests.PropertiesObject(some_long=-42)
1051 self.assertEqual(self.get_prop(obj, 'some-long'), -42)
1053 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-long', 'foo')
1054 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-long', None)
1056 self.assertEqual(self.get_prop(obj, 'some-long'), -42)
1058 def test_ulong(self):
1059 self.assertEqual(self.get_prop(self.obj, 'some_ulong'), 0)
1060 self.set_prop(self.obj, 'some-ulong', GLib.MAXULONG)
1061 self.assertEqual(self.get_prop(self.obj, 'some_ulong'), GLib.MAXULONG)
1063 obj = GIMarshallingTests.PropertiesObject(some_ulong=42)
1064 self.assertEqual(self.get_prop(obj, 'some-ulong'), 42)
1066 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-ulong', 'foo')
1067 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-ulong', None)
1069 self.assertEqual(self.get_prop(obj, 'some-ulong'), 42)
1071 def test_int64(self):
1072 self.assertEqual(self.get_prop(self.obj, 'some-int64'), 0)
1073 self.set_prop(self.obj, 'some-int64', GLib.MAXINT64)
1074 self.assertEqual(self.get_prop(self.obj, 'some-int64'), GLib.MAXINT64)
1076 obj = GIMarshallingTests.PropertiesObject(some_int64=-4200000000000000)
1077 self.assertEqual(self.get_prop(obj, 'some-int64'), -4200000000000000)
1079 def test_uint64(self):
1080 self.assertEqual(self.get_prop(self.obj, 'some-uint64'), 0)
1081 self.set_prop(self.obj, 'some-uint64', GLib.MAXUINT64)
1082 self.assertEqual(self.get_prop(self.obj, 'some-uint64'), GLib.MAXUINT64)
1084 obj = GIMarshallingTests.PropertiesObject(some_uint64=4200000000000000)
1085 self.assertEqual(self.get_prop(obj, 'some-uint64'), 4200000000000000)
1087 def test_float(self):
1088 self.assertEqual(self.get_prop(self.obj, 'some-float'), 0)
1089 self.set_prop(self.obj, 'some-float', GLib.MAXFLOAT)
1090 self.assertEqual(self.get_prop(self.obj, 'some-float'), GLib.MAXFLOAT)
1092 obj = GIMarshallingTests.PropertiesObject(some_float=42.42)
1093 self.assertAlmostEqual(self.get_prop(obj, 'some-float'), 42.42, places=4)
1095 obj = GIMarshallingTests.PropertiesObject(some_float=42)
1096 self.assertAlmostEqual(self.get_prop(obj, 'some-float'), 42.0, places=4)
1098 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-float', 'foo')
1099 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-float', None)
1101 self.assertAlmostEqual(self.get_prop(obj, 'some-float'), 42.0, places=4)
1103 def test_double(self):
1104 self.assertEqual(self.get_prop(self.obj, 'some-double'), 0)
1105 self.set_prop(self.obj, 'some-double', GLib.MAXDOUBLE)
1106 self.assertEqual(self.get_prop(self.obj, 'some-double'), GLib.MAXDOUBLE)
1108 obj = GIMarshallingTests.PropertiesObject(some_double=42.42)
1109 self.assertAlmostEqual(self.get_prop(obj, 'some-double'), 42.42)
1111 obj = GIMarshallingTests.PropertiesObject(some_double=42)
1112 self.assertAlmostEqual(self.get_prop(obj, 'some-double'), 42.0)
1114 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-double', 'foo')
1115 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-double', None)
1117 self.assertAlmostEqual(self.get_prop(obj, 'some-double'), 42.0)
1119 def test_strv(self):
1120 self.assertEqual(self.get_prop(self.obj, 'some-strv'), [])
1121 self.set_prop(self.obj, 'some-strv', ['hello', 'world'])
1122 self.assertEqual(self.get_prop(self.obj, 'some-strv'), ['hello', 'world'])
1124 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-strv', 1)
1125 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-strv', 'foo')
1126 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-strv', [1, 2])
1127 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-strv', ['foo', 1])
1129 self.assertEqual(self.get_prop(self.obj, 'some-strv'), ['hello', 'world'])
1131 obj = GIMarshallingTests.PropertiesObject(some_strv=['hello', 'world'])
1132 self.assertEqual(self.get_prop(obj, 'some-strv'), ['hello', 'world'])
1134 # unicode on py2
1135 obj = GIMarshallingTests.PropertiesObject(some_strv=[u'foo'])
1136 self.assertEqual(self.get_prop(obj, 'some-strv'), [u'foo'])
1137 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-strv',
1138 [u'foo', 1])
1140 def test_boxed_struct(self):
1141 self.assertEqual(self.get_prop(self.obj, 'some-boxed-struct'), None)
1143 class GStrv(list):
1144 __gtype__ = GObject.TYPE_STRV
1146 struct1 = GIMarshallingTests.BoxedStruct()
1147 struct1.long_ = 1
1149 self.set_prop(self.obj, 'some-boxed-struct', struct1)
1150 self.assertEqual(self.get_prop(self.obj, 'some-boxed-struct').long_, 1)
1151 self.assertEqual(self.obj.some_boxed_struct.long_, 1)
1153 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-boxed-struct', 1)
1154 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-boxed-struct', 'foo')
1156 obj = GIMarshallingTests.PropertiesObject(some_boxed_struct=struct1)
1157 self.assertEqual(self.get_prop(obj, 'some-boxed-struct').long_, 1)
1159 def test_boxed_glist(self):
1160 self.assertEqual(self.get_prop(self.obj, 'some-boxed-glist'), [])
1162 list_ = [GLib.MININT, 42, GLib.MAXINT]
1163 self.set_prop(self.obj, 'some-boxed-glist', list_)
1164 self.assertEqual(self.get_prop(self.obj, 'some-boxed-glist'), list_)
1165 self.set_prop(self.obj, 'some-boxed-glist', [])
1166 self.assertEqual(self.get_prop(self.obj, 'some-boxed-glist'), [])
1168 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-boxed-glist', 1)
1169 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-boxed-glist', 'foo')
1170 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-boxed-glist', ['a'])
1172 def test_annotated_glist(self):
1173 obj = Regress.TestObj()
1174 self.assertEqual(self.get_prop(obj, 'list'), [])
1176 self.set_prop(obj, 'list', ['1', '2', '3'])
1177 self.assertTrue(isinstance(self.get_prop(obj, 'list'), list))
1178 self.assertEqual(self.get_prop(obj, 'list'), ['1', '2', '3'])
1180 @unittest.expectedFailure
1181 def test_boxed_glist_ctor(self):
1182 list_ = [GLib.MININT, 42, GLib.MAXINT]
1183 obj = GIMarshallingTests.PropertiesObject(some_boxed_glist=list_)
1184 self.assertEqual(self.get_prop(obj, 'some-boxed-glist'), list_)
1186 def test_variant(self):
1187 self.assertEqual(self.get_prop(self.obj, 'some-variant'), None)
1189 self.set_prop(self.obj, 'some-variant', GLib.Variant('o', '/myobj'))
1190 self.assertEqual(self.get_prop(self.obj, 'some-variant').get_type_string(), 'o')
1191 self.assertEqual(self.get_prop(self.obj, 'some-variant').print_(False), "'/myobj'")
1193 self.set_prop(self.obj, 'some-variant', None)
1194 self.assertEqual(self.get_prop(self.obj, 'some-variant'), None)
1196 obj = GIMarshallingTests.PropertiesObject(some_variant=GLib.Variant('b', True))
1197 self.assertEqual(self.get_prop(obj, 'some-variant').get_type_string(), 'b')
1198 self.assertEqual(self.get_prop(obj, 'some-variant').get_boolean(), True)
1200 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-variant', 'foo')
1201 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-variant', 23)
1203 self.assertEqual(self.get_prop(obj, 'some-variant').get_type_string(), 'b')
1204 self.assertEqual(self.get_prop(obj, 'some-variant').get_boolean(), True)
1206 def test_setting_several_properties(self):
1207 obj = GIMarshallingTests.PropertiesObject()
1208 obj.set_properties(some_uchar=54, some_int=42)
1209 self.assertEqual(42, self.get_prop(obj, 'some-int'))
1210 self.assertEqual(54, self.get_prop(obj, 'some-uchar'))
1212 def test_gtype(self):
1213 obj = Regress.TestObj()
1214 self.assertEqual(self.get_prop(obj, 'gtype'), GObject.TYPE_INVALID)
1215 self.set_prop(obj, 'gtype', int)
1216 self.assertEqual(self.get_prop(obj, 'gtype'), GObject.TYPE_INT)
1218 obj = Regress.TestObj(gtype=int)
1219 self.assertEqual(self.get_prop(obj, 'gtype'), GObject.TYPE_INT)
1220 self.set_prop(obj, 'gtype', str)
1221 self.assertEqual(self.get_prop(obj, 'gtype'), GObject.TYPE_STRING)
1223 def test_hash_table(self):
1224 obj = Regress.TestObj()
1225 self.assertEqual(self.get_prop(obj, 'hash-table'), None)
1227 self.set_prop(obj, 'hash-table', {'mec': 56})
1228 self.assertTrue(isinstance(self.get_prop(obj, 'hash-table'), dict))
1229 self.assertEqual(list(self.get_prop(obj, 'hash-table').items())[0],
1230 ('mec', 56))
1232 def test_parent_class(self):
1233 class A(Regress.TestObj):
1234 prop1 = GObject.Property(type=int)
1236 a = A()
1237 self.set_prop(a, 'int', 20)
1238 self.assertEqual(self.get_prop(a, 'int'), 20)
1240 # test parent property which needs introspection
1241 self.set_prop(a, 'list', ("str1", "str2"))
1242 self.assertEqual(self.get_prop(a, 'list'), ["str1", "str2"])
1244 def test_held_object_ref_count_getter(self):
1245 holder = GIMarshallingTests.PropertiesObject()
1246 held = GObject.Object()
1248 self.assertEqual(holder.__grefcount__, 1)
1249 self.assertEqual(held.__grefcount__, 1)
1251 self.set_prop(holder, 'some-object', held)
1252 self.assertEqual(holder.__grefcount__, 1)
1254 initial_ref_count = held.__grefcount__
1255 self.get_prop(holder, 'some-object')
1256 gc.collect()
1257 self.assertEqual(held.__grefcount__, initial_ref_count)
1259 def test_held_object_ref_count_setter(self):
1260 holder = GIMarshallingTests.PropertiesObject()
1261 held = GObject.Object()
1263 self.assertEqual(holder.__grefcount__, 1)
1264 self.assertEqual(held.__grefcount__, 1)
1266 # Setting property should only increase ref count by 1
1267 self.set_prop(holder, 'some-object', held)
1268 self.assertEqual(holder.__grefcount__, 1)
1269 self.assertEqual(held.__grefcount__, 2)
1271 # Clearing should pull it back down
1272 self.set_prop(holder, 'some-object', None)
1273 self.assertEqual(held.__grefcount__, 1)
1275 def test_set_object_property_to_invalid_type(self):
1276 obj = GIMarshallingTests.PropertiesObject()
1277 self.assertRaises(TypeError, self.set_prop, obj, 'some-object', 'not_an_object')
1280 class TestCPropsAccessor(CPropertiesTestBase, unittest.TestCase):
1281 # C property tests using the "props" accessor.
1282 def get_prop(self, obj, name):
1283 return getattr(obj.props, name.replace('-', '_'))
1285 def set_prop(self, obj, name, value):
1286 setattr(obj.props, name.replace('-', '_'), value)
1288 def test_props_accessor_dir(self):
1289 # Test class
1290 props = dir(GIMarshallingTests.PropertiesObject.props)
1291 self.assertTrue('some_float' in props)
1292 self.assertTrue('some_double' in props)
1293 self.assertTrue('some_variant' in props)
1295 # Test instance
1296 obj = GIMarshallingTests.PropertiesObject()
1297 props = dir(obj.props)
1298 self.assertTrue('some_float' in props)
1299 self.assertTrue('some_double' in props)
1300 self.assertTrue('some_variant' in props)
1302 def test_param_spec_dir(self):
1303 attrs = dir(GIMarshallingTests.PropertiesObject.props.some_float)
1304 self.assertTrue('name' in attrs)
1305 self.assertTrue('nick' in attrs)
1306 self.assertTrue('blurb' in attrs)
1307 self.assertTrue('flags' in attrs)
1308 self.assertTrue('default_value' in attrs)
1309 self.assertTrue('minimum' in attrs)
1310 self.assertTrue('maximum' in attrs)
1313 class TestCGetPropertyMethod(CPropertiesTestBase, unittest.TestCase):
1314 # C property tests using the "props" accessor.
1315 def get_prop(self, obj, name):
1316 return obj.get_property(name)
1318 def set_prop(self, obj, name, value):
1319 obj.set_property(name, value)
1322 if __name__ == '__main__':
1323 unittest.main()