functions: revert the function init order to make pylint happy again. See #217
[pygobject.git] / tests / test_properties.py
blob35b03b71511be30e3cf873feaf8dbcd731e5bfcb
1 # coding=utf-8
3 from __future__ import absolute_import
5 import os
6 import gc
7 import sys
8 import struct
9 import types
10 import unittest
11 import tempfile
13 import pytest
15 from gi.repository import GObject
16 from gi.repository.GObject import ParamFlags, GType, new
17 from gi.repository.GObject import \
18 TYPE_INT, TYPE_UINT, TYPE_LONG, TYPE_ULONG, TYPE_INT64, \
19 TYPE_UINT64, TYPE_GTYPE, TYPE_INVALID, TYPE_NONE, TYPE_STRV, \
20 TYPE_INTERFACE, TYPE_CHAR, TYPE_UCHAR, TYPE_BOOLEAN, TYPE_FLOAT, \
21 TYPE_DOUBLE, TYPE_POINTER, TYPE_BOXED, TYPE_PARAM, TYPE_OBJECT, \
22 TYPE_STRING, TYPE_PYOBJECT, TYPE_VARIANT
24 from gi.repository.GLib import \
25 MININT, MAXINT, MAXUINT, MINLONG, MAXLONG, MAXULONG, \
26 MAXUINT64, MAXINT64, MININT64
28 from gi.repository import Gio
29 from gi.repository import GLib
30 from gi.repository import GIMarshallingTests
31 from gi.repository import Regress
32 from gi import _propertyhelper as propertyhelper
34 from gi._compat import long_, PY3, PY2
35 from .helper import capture_glib_warnings
38 class PropertyObject(GObject.GObject):
39 normal = GObject.Property(type=str)
40 construct = GObject.Property(
41 type=str,
42 flags=ParamFlags.READABLE | ParamFlags.WRITABLE | ParamFlags.CONSTRUCT,
43 default='default')
45 construct_only = GObject.Property(
46 type=str,
47 flags=ParamFlags.READABLE | ParamFlags.WRITABLE | ParamFlags.CONSTRUCT_ONLY)
49 uint64 = GObject.Property(
50 type=TYPE_UINT64,
51 flags=ParamFlags.READABLE | ParamFlags.WRITABLE | ParamFlags.CONSTRUCT)
53 enum = GObject.Property(
54 type=Gio.SocketType, default=Gio.SocketType.STREAM)
56 boxed = GObject.Property(
57 type=GLib.Regex,
58 flags=ParamFlags.READABLE | ParamFlags.WRITABLE | ParamFlags.CONSTRUCT)
60 flags = GObject.Property(
61 type=GIMarshallingTests.Flags,
62 flags=ParamFlags.READABLE | ParamFlags.WRITABLE | ParamFlags.CONSTRUCT,
63 default=GIMarshallingTests.Flags.VALUE1)
65 gtype = GObject.Property(
66 type=TYPE_GTYPE,
67 flags=ParamFlags.READABLE | ParamFlags.WRITABLE | ParamFlags.CONSTRUCT)
69 strings = GObject.Property(
70 type=TYPE_STRV,
71 flags=ParamFlags.READABLE | ParamFlags.WRITABLE | ParamFlags.CONSTRUCT)
73 variant = GObject.Property(
74 type=TYPE_VARIANT,
75 flags=ParamFlags.READABLE | ParamFlags.WRITABLE | ParamFlags.CONSTRUCT)
77 variant_def = GObject.Property(
78 type=TYPE_VARIANT,
79 flags=ParamFlags.READABLE | ParamFlags.WRITABLE | ParamFlags.CONSTRUCT,
80 default=GLib.Variant('i', 42))
82 interface = GObject.Property(
83 type=Gio.File,
84 flags=ParamFlags.READABLE | ParamFlags.WRITABLE | ParamFlags.CONSTRUCT)
87 class PropertyInheritanceObject(Regress.TestObj):
88 # override property from the base class, with a different type
89 string = GObject.Property(type=int)
91 # a property entirely defined at the Python level
92 python_prop = GObject.Property(type=str)
95 class PropertySubClassObject(PropertyInheritanceObject):
96 # override property from the base class, with a different type
97 python_prop = GObject.Property(type=int)
100 class TestPropertyInheritanceObject(unittest.TestCase):
101 def test_override_gi_property(self):
102 self.assertNotEqual(Regress.TestObj.props.string.value_type,
103 PropertyInheritanceObject.props.string.value_type)
104 obj = PropertyInheritanceObject()
105 self.assertEqual(type(obj.props.string), int)
106 obj.props.string = 4
107 self.assertEqual(obj.props.string, 4)
109 def test_override_python_property(self):
110 obj = PropertySubClassObject()
111 self.assertEqual(type(obj.props.python_prop), int)
112 obj.props.python_prop = 5
113 self.assertEqual(obj.props.python_prop, 5)
116 class TestPropertyObject(unittest.TestCase):
117 def test_get_set(self):
118 obj = PropertyObject()
119 obj.props.normal = "value"
120 self.assertEqual(obj.props.normal, "value")
122 def test_hasattr_on_object(self):
123 obj = PropertyObject()
124 self.assertTrue(hasattr(obj.props, "normal"))
126 def test_hasattr_on_class(self):
127 self.assertTrue(hasattr(PropertyObject.props, "normal"))
129 def test_set_on_class(self):
130 def set(obj):
131 obj.props.normal = "foobar"
133 self.assertRaises(TypeError, set, PropertyObject)
135 def test_iteration(self):
136 for obj in (PropertyObject.props, PropertyObject().props):
137 names = []
138 for pspec in obj:
139 gtype = GType(pspec)
140 self.assertEqual(gtype.parent.name, 'GParam')
141 names.append(pspec.name)
143 names.sort()
144 self.assertEqual(names, ['boxed',
145 'construct',
146 'construct-only',
147 'enum',
148 'flags',
149 'gtype',
150 'interface',
151 'normal',
152 'strings',
153 'uint64',
154 'variant',
155 'variant-def'])
157 def test_normal(self):
158 obj = new(PropertyObject, normal="123")
159 self.assertEqual(obj.props.normal, "123")
160 obj.set_property('normal', '456')
161 self.assertEqual(obj.props.normal, "456")
162 obj.props.normal = '789'
163 self.assertEqual(obj.props.normal, "789")
165 def test_construct(self):
166 obj = new(PropertyObject, construct="123")
167 self.assertEqual(obj.props.construct, "123")
168 obj.set_property('construct', '456')
169 self.assertEqual(obj.props.construct, "456")
170 obj.props.construct = '789'
171 self.assertEqual(obj.props.construct, "789")
173 def test_utf8(self):
174 test_utf8 = "♥"
175 unicode_utf8 = u"♥"
176 obj = new(PropertyObject, construct_only=unicode_utf8)
177 self.assertEqual(obj.props.construct_only, test_utf8)
178 obj.set_property('construct', unicode_utf8)
179 self.assertEqual(obj.props.construct, test_utf8)
180 obj.props.normal = unicode_utf8
181 self.assertEqual(obj.props.normal, test_utf8)
183 def test_utf8_lone_surrogate(self):
184 obj = PropertyObject()
185 if PY3:
186 with pytest.raises(TypeError):
187 obj.set_property('construct', '\ud83d')
188 else:
189 obj.set_property('construct', '\ud83d')
191 def test_int_to_str(self):
192 obj = new(PropertyObject, construct_only=1)
193 self.assertEqual(obj.props.construct_only, '1')
194 obj.set_property('construct', '2')
195 self.assertEqual(obj.props.construct, '2')
196 obj.props.normal = 3
197 self.assertEqual(obj.props.normal, '3')
199 def test_construct_only(self):
200 obj = new(PropertyObject, construct_only="123")
201 self.assertEqual(obj.props.construct_only, "123")
202 self.assertRaises(TypeError,
203 setattr, obj.props, 'construct_only', '456')
204 self.assertRaises(TypeError,
205 obj.set_property, 'construct-only', '456')
207 def test_uint64(self):
208 obj = new(PropertyObject)
209 self.assertEqual(obj.props.uint64, 0)
210 obj.props.uint64 = long_(1)
211 self.assertEqual(obj.props.uint64, long_(1))
212 obj.props.uint64 = 1
213 self.assertEqual(obj.props.uint64, long_(1))
215 self.assertRaises((TypeError, OverflowError), obj.set_property, "uint64", long_(-1))
216 self.assertRaises((TypeError, OverflowError), obj.set_property, "uint64", -1)
218 def test_uint64_default_value(self):
219 try:
220 class TimeControl(GObject.GObject):
221 __gproperties__ = {
222 'time': (TYPE_UINT64, 'Time', 'Time',
223 long_(0), (1 << 64) - 1, long_(0),
224 ParamFlags.READABLE)
226 except OverflowError:
227 (etype, ex) = sys.exc_info()[2:]
228 self.fail(str(ex))
230 def test_enum(self):
231 obj = new(PropertyObject)
232 self.assertEqual(obj.props.enum, Gio.SocketType.STREAM)
233 self.assertEqual(obj.enum, Gio.SocketType.STREAM)
234 obj.enum = Gio.SocketType.DATAGRAM
235 self.assertEqual(obj.props.enum, Gio.SocketType.DATAGRAM)
236 self.assertEqual(obj.enum, Gio.SocketType.DATAGRAM)
237 obj.props.enum = Gio.SocketType.STREAM
238 self.assertEqual(obj.props.enum, Gio.SocketType.STREAM)
239 self.assertEqual(obj.enum, Gio.SocketType.STREAM)
240 obj.props.enum = 2
241 self.assertEqual(obj.props.enum, Gio.SocketType.DATAGRAM)
242 self.assertEqual(obj.enum, Gio.SocketType.DATAGRAM)
243 obj.enum = 1
244 self.assertEqual(obj.props.enum, Gio.SocketType.STREAM)
245 self.assertEqual(obj.enum, Gio.SocketType.STREAM)
247 self.assertRaises(TypeError, setattr, obj, 'enum', 'foo')
248 self.assertRaises(TypeError, setattr, obj, 'enum', object())
250 self.assertRaises(TypeError, GObject.Property, type=Gio.SocketType)
251 self.assertRaises(TypeError, GObject.Property, type=Gio.SocketType,
252 default=Gio.SocketProtocol.TCP)
253 self.assertRaises(TypeError, GObject.Property, type=Gio.SocketType,
254 default=object())
255 self.assertRaises(TypeError, GObject.Property, type=Gio.SocketType,
256 default=1)
258 def test_repr(self):
259 prop = GObject.Property(type=int)
260 assert repr(prop) == "<GObject Property (uninitialized) (gint)>"
262 def test_flags(self):
263 obj = new(PropertyObject)
264 self.assertEqual(obj.props.flags, GIMarshallingTests.Flags.VALUE1)
265 self.assertEqual(obj.flags, GIMarshallingTests.Flags.VALUE1)
267 obj.flags = GIMarshallingTests.Flags.VALUE2 | GIMarshallingTests.Flags.VALUE3
268 self.assertEqual(obj.props.flags, GIMarshallingTests.Flags.VALUE2 | GIMarshallingTests.Flags.VALUE3)
269 self.assertEqual(obj.flags, GIMarshallingTests.Flags.VALUE2 | GIMarshallingTests.Flags.VALUE3)
271 self.assertRaises(TypeError, setattr, obj, 'flags', 'foo')
272 self.assertRaises(TypeError, setattr, obj, 'flags', object())
273 self.assertRaises(TypeError, setattr, obj, 'flags', None)
275 self.assertRaises(TypeError, GObject.Property,
276 type=GIMarshallingTests.Flags, default='foo')
277 self.assertRaises(TypeError, GObject.Property,
278 type=GIMarshallingTests.Flags, default=object())
279 self.assertRaises(TypeError, GObject.Property,
280 type=GIMarshallingTests.Flags, default=None)
282 def test_gtype(self):
283 obj = new(PropertyObject)
285 self.assertEqual(obj.props.gtype, TYPE_NONE)
286 self.assertEqual(obj.gtype, TYPE_NONE)
288 obj.gtype = TYPE_UINT64
289 self.assertEqual(obj.props.gtype, TYPE_UINT64)
290 self.assertEqual(obj.gtype, TYPE_UINT64)
292 obj.gtype = TYPE_INVALID
293 self.assertEqual(obj.props.gtype, TYPE_INVALID)
294 self.assertEqual(obj.gtype, TYPE_INVALID)
296 # GType parameters do not support defaults in GLib
297 self.assertRaises(TypeError, GObject.Property, type=TYPE_GTYPE,
298 default=TYPE_INT)
300 # incompatible type
301 self.assertRaises(TypeError, setattr, obj, 'gtype', 'foo')
302 self.assertRaises(TypeError, setattr, obj, 'gtype', object())
304 self.assertRaises(TypeError, GObject.Property, type=TYPE_GTYPE,
305 default='foo')
306 self.assertRaises(TypeError, GObject.Property, type=TYPE_GTYPE,
307 default=object())
309 # set in constructor
310 obj = new(PropertyObject, gtype=TYPE_UINT)
311 self.assertEqual(obj.props.gtype, TYPE_UINT)
312 self.assertEqual(obj.gtype, TYPE_UINT)
314 def test_boxed(self):
315 obj = new(PropertyObject)
317 regex = GLib.Regex.new('[a-z]*', 0, 0)
318 obj.props.boxed = regex
319 self.assertEqual(obj.props.boxed.get_pattern(), '[a-z]*')
320 self.assertEqual(obj.boxed.get_pattern(), '[a-z]*')
322 self.assertRaises(TypeError, setattr, obj, 'boxed', 'foo')
323 self.assertRaises(TypeError, setattr, obj, 'boxed', object())
325 def test_strings(self):
326 obj = new(PropertyObject)
328 # Should work with actual GStrv objects as well as
329 # Python string lists
330 class GStrv(list):
331 __gtype__ = GObject.TYPE_STRV
333 self.assertEqual(obj.props.strings, GStrv([]))
334 self.assertEqual(obj.strings, GStrv([]))
335 self.assertEqual(obj.props.strings, [])
336 self.assertEqual(obj.strings, [])
338 obj.strings = ['hello', 'world']
339 self.assertEqual(obj.props.strings, ['hello', 'world'])
340 self.assertEqual(obj.strings, ['hello', 'world'])
342 obj.strings = GStrv(['hello', 'world'])
343 self.assertEqual(obj.props.strings, GStrv(['hello', 'world']))
344 self.assertEqual(obj.strings, GStrv(['hello', 'world']))
346 obj.strings = []
347 self.assertEqual(obj.strings, [])
348 obj.strings = GStrv([])
349 self.assertEqual(obj.strings, GStrv([]))
351 p = GObject.Property(type=TYPE_STRV, default=['hello', '1'])
352 self.assertEqual(p.default, ['hello', '1'])
353 self.assertEqual(p.type, TYPE_STRV)
354 p = GObject.Property(type=TYPE_STRV, default=GStrv(['hello', '1']))
355 self.assertEqual(p.default, ['hello', '1'])
356 self.assertEqual(p.type, TYPE_STRV)
358 # set in constructor
359 obj = new(PropertyObject, strings=['hello', 'world'])
360 self.assertEqual(obj.props.strings, ['hello', 'world'])
361 self.assertEqual(obj.strings, ['hello', 'world'])
363 # wrong types
364 self.assertRaises(TypeError, setattr, obj, 'strings', 1)
365 self.assertRaises(TypeError, setattr, obj, 'strings', 'foo')
366 self.assertRaises(TypeError, setattr, obj, 'strings', ['foo', 1])
368 self.assertRaises(TypeError, GObject.Property, type=TYPE_STRV,
369 default=1)
370 self.assertRaises(TypeError, GObject.Property, type=TYPE_STRV,
371 default='foo')
372 self.assertRaises(TypeError, GObject.Property, type=TYPE_STRV,
373 default=['hello', 1])
375 def test_variant(self):
376 obj = new(PropertyObject)
378 self.assertEqual(obj.props.variant, None)
379 self.assertEqual(obj.variant, None)
381 obj.variant = GLib.Variant('s', 'hello')
382 self.assertEqual(obj.variant.print_(True), "'hello'")
384 obj.variant = GLib.Variant('b', True)
385 self.assertEqual(obj.variant.print_(True), "true")
387 obj.props.variant = GLib.Variant('y', 2)
388 self.assertEqual(obj.variant.print_(True), "byte 0x02")
390 obj.variant = None
391 self.assertEqual(obj.variant, None)
393 # set in constructor
394 obj = new(PropertyObject, variant=GLib.Variant('u', 5))
395 self.assertEqual(obj.props.variant.print_(True), 'uint32 5')
397 GObject.Property(type=TYPE_VARIANT, default=GLib.Variant('i', 1))
399 # incompatible types
400 self.assertRaises(TypeError, setattr, obj, 'variant', 'foo')
401 self.assertRaises(TypeError, setattr, obj, 'variant', 42)
403 self.assertRaises(TypeError, GObject.Property, type=TYPE_VARIANT,
404 default='foo')
405 self.assertRaises(TypeError, GObject.Property, type=TYPE_VARIANT,
406 default=object())
408 def test_variant_default(self):
409 obj = new(PropertyObject)
411 self.assertEqual(obj.props.variant_def.print_(True), '42')
412 self.assertEqual(obj.variant_def.print_(True), '42')
414 obj.props.variant_def = GLib.Variant('y', 2)
415 self.assertEqual(obj.variant_def.print_(True), "byte 0x02")
417 # set in constructor
418 obj = new(PropertyObject, variant_def=GLib.Variant('u', 5))
419 self.assertEqual(obj.props.variant_def.print_(True), 'uint32 5')
421 def test_interface(self):
422 obj = new(PropertyObject)
424 path = os.path.join(tempfile.gettempdir(), "some", "path")
425 file = Gio.File.new_for_path(path)
426 obj.props.interface = file
427 self.assertEqual(obj.props.interface.get_path(), path)
428 self.assertEqual(obj.interface.get_path(), path)
430 self.assertRaises(TypeError, setattr, obj, 'interface', 'foo')
431 self.assertRaises(TypeError, setattr, obj, 'interface', object())
433 def test_range(self):
434 # kiwi code
435 def max(c):
436 return 2 ** ((8 * struct.calcsize(c)) - 1) - 1
438 def umax(c):
439 return 2 ** (8 * struct.calcsize(c)) - 1
441 maxint = max('i')
442 minint = -maxint - 1
443 maxuint = umax('I')
444 maxlong = max('l')
445 minlong = -maxlong - 1
446 maxulong = umax('L')
447 maxint64 = max('q')
448 minint64 = -maxint64 - 1
449 maxuint64 = umax('Q')
451 types_ = dict(int=(TYPE_INT, minint, maxint),
452 uint=(TYPE_UINT, 0, maxuint),
453 long=(TYPE_LONG, minlong, maxlong),
454 ulong=(TYPE_ULONG, 0, maxulong),
455 int64=(TYPE_INT64, minint64, maxint64),
456 uint64=(TYPE_UINT64, 0, maxuint64))
458 def build_gproperties(types_):
459 d = {}
460 for key, (gtype, min, max) in types_.items():
461 d[key] = (gtype, 'blurb', 'desc', min, max, 0,
462 ParamFlags.READABLE | ParamFlags.WRITABLE)
463 return d
465 class RangeCheck(GObject.GObject):
466 __gproperties__ = build_gproperties(types_)
468 def __init__(self):
469 self.values = {}
470 GObject.GObject.__init__(self)
472 def do_set_property(self, pspec, value):
473 self.values[pspec.name] = value
475 def do_get_property(self, pspec):
476 return self.values.get(pspec.name, pspec.default_value)
478 self.assertEqual(RangeCheck.props.int.minimum, minint)
479 self.assertEqual(RangeCheck.props.int.maximum, maxint)
480 self.assertEqual(RangeCheck.props.uint.minimum, 0)
481 self.assertEqual(RangeCheck.props.uint.maximum, maxuint)
482 self.assertEqual(RangeCheck.props.long.minimum, minlong)
483 self.assertEqual(RangeCheck.props.long.maximum, maxlong)
484 self.assertEqual(RangeCheck.props.ulong.minimum, 0)
485 self.assertEqual(RangeCheck.props.ulong.maximum, maxulong)
486 self.assertEqual(RangeCheck.props.int64.minimum, minint64)
487 self.assertEqual(RangeCheck.props.int64.maximum, maxint64)
488 self.assertEqual(RangeCheck.props.uint64.minimum, 0)
489 self.assertEqual(RangeCheck.props.uint64.maximum, maxuint64)
491 obj = RangeCheck()
492 for key, (gtype, min, max) in types_.items():
493 self.assertEqual(obj.get_property(key),
494 getattr(RangeCheck.props, key).default_value)
496 obj.set_property(key, min)
497 self.assertEqual(obj.get_property(key), min)
499 obj.set_property(key, max)
500 self.assertEqual(obj.get_property(key), max)
502 def test_multi(self):
503 obj = PropertyObject()
504 obj.set_properties(normal="foo",
505 uint64=7)
506 normal, uint64 = obj.get_properties("normal", "uint64")
507 self.assertEqual(normal, "foo")
508 self.assertEqual(uint64, 7)
511 class TestProperty(unittest.TestCase):
512 def test_simple(self):
513 class C(GObject.GObject):
514 str = GObject.Property(type=str)
515 int = GObject.Property(type=int)
516 float = GObject.Property(type=float)
517 long = GObject.Property(type=long_)
519 self.assertTrue(hasattr(C.props, 'str'))
520 self.assertTrue(hasattr(C.props, 'int'))
521 self.assertTrue(hasattr(C.props, 'float'))
522 self.assertTrue(hasattr(C.props, 'long'))
524 o = C()
525 self.assertEqual(o.str, '')
526 o.str = 'str'
527 self.assertEqual(o.str, 'str')
529 self.assertEqual(o.int, 0)
530 o.int = 1138
531 self.assertEqual(o.int, 1138)
533 self.assertEqual(o.float, 0.0)
534 o.float = 3.14
535 self.assertEqual(o.float, 3.14)
537 self.assertEqual(o.long, long_(0))
538 o.long = long_(100)
539 self.assertEqual(o.long, long_(100))
541 def test_custom_getter(self):
542 class C(GObject.GObject):
543 def get_prop(self):
544 return 'value'
545 prop = GObject.Property(getter=get_prop)
547 o = C()
548 self.assertEqual(o.prop, 'value')
549 self.assertRaises(TypeError, setattr, o, 'prop', 'xxx')
551 def test_getter_exception(self):
552 class C(GObject.Object):
553 @GObject.Property(type=int)
554 def prop(self):
555 raise ValueError('something bad happend')
557 o = C()
559 with self.assertRaisesRegex(ValueError, 'something bad happend'):
560 o.prop
562 with self.assertRaisesRegex(ValueError, 'something bad happend'):
563 o.get_property('prop')
565 with self.assertRaisesRegex(ValueError, 'something bad happend'):
566 o.props.prop
568 def test_custom_setter(self):
569 class C(GObject.GObject):
570 def set_prop(self, value):
571 self._value = value
572 prop = GObject.Property(setter=set_prop)
574 def __init__(self):
575 self._value = None
576 GObject.GObject.__init__(self)
578 o = C()
579 self.assertEqual(o._value, None)
580 o.prop = 'bar'
581 self.assertEqual(o._value, 'bar')
582 self.assertRaises(TypeError, getattr, o, 'prop')
584 def test_decorator_default(self):
585 class C(GObject.GObject):
586 _value = 'value'
588 @GObject.Property
589 def value(self):
590 return self._value
592 @value.setter
593 def value_setter(self, value):
594 self._value = value
596 o = C()
597 self.assertEqual(o.value, 'value')
598 o.value = 'blah'
599 self.assertEqual(o.value, 'blah')
600 self.assertEqual(o.props.value, 'blah')
602 def test_decorator_private_setter(self):
603 class C(GObject.GObject):
604 _value = 'value'
606 @GObject.Property
607 def value(self):
608 return self._value
610 @value.setter
611 def _set_value(self, value):
612 self._value = value
614 o = C()
615 self.assertEqual(o.value, 'value')
616 o.value = 'blah'
617 self.assertEqual(o.value, 'blah')
618 self.assertEqual(o.props.value, 'blah')
620 def test_decorator_with_call(self):
621 class C(GObject.GObject):
622 _value = 1
624 @GObject.Property(type=int, default=1, minimum=1, maximum=10)
625 def typedValue(self):
626 return self._value
628 @typedValue.setter
629 def typedValue_setter(self, value):
630 self._value = value
632 o = C()
633 self.assertEqual(o.typedValue, 1)
634 o.typedValue = 5
635 self.assertEqual(o.typedValue, 5)
636 self.assertEqual(o.props.typedValue, 5)
638 def test_errors(self):
639 self.assertRaises(TypeError, GObject.Property, type='str')
640 self.assertRaises(TypeError, GObject.Property, nick=False)
641 self.assertRaises(TypeError, GObject.Property, blurb=False)
642 # this never fail while bool is a subclass of int
643 # >>> bool.__bases__
644 # (<type 'int'>,)
645 # self.assertRaises(TypeError, GObject.Property, type=bool, default=0)
646 self.assertRaises(TypeError, GObject.Property, type=bool, default='ciao mamma')
647 self.assertRaises(TypeError, GObject.Property, type=bool)
648 self.assertRaises(TypeError, GObject.Property, type=object, default=0)
649 self.assertRaises(TypeError, GObject.Property, type=complex)
651 def test_defaults(self):
652 GObject.Property(type=bool, default=True)
653 GObject.Property(type=bool, default=False)
655 def test_name_with_underscore(self):
656 class C(GObject.GObject):
657 prop_name = GObject.Property(type=int)
658 o = C()
659 o.prop_name = 10
660 self.assertEqual(o.prop_name, 10)
662 def test_range(self):
663 types_ = [
664 (TYPE_INT, MININT, MAXINT),
665 (TYPE_UINT, 0, MAXUINT),
666 (TYPE_LONG, MINLONG, MAXLONG),
667 (TYPE_ULONG, 0, MAXULONG),
668 (TYPE_INT64, MININT64, MAXINT64),
669 (TYPE_UINT64, 0, MAXUINT64),
672 for gtype, min, max in types_:
673 # Normal, everything is alright
674 prop = GObject.Property(type=gtype, minimum=min, maximum=max)
675 subtype = type('', (GObject.GObject,), dict(prop=prop))
676 self.assertEqual(subtype.props.prop.minimum, min)
677 self.assertEqual(subtype.props.prop.maximum, max)
679 # Lower than minimum
680 self.assertRaises(TypeError,
681 GObject.Property, type=gtype, minimum=min - 1,
682 maximum=max)
684 # Higher than maximum
685 self.assertRaises(TypeError,
686 GObject.Property, type=gtype, minimum=min,
687 maximum=max + 1)
689 def test_min_max(self):
690 class C(GObject.GObject):
691 prop_int = GObject.Property(type=int, minimum=1, maximum=100, default=1)
692 prop_float = GObject.Property(type=float, minimum=0.1, maximum=10.5, default=1.1)
694 def __init__(self):
695 GObject.GObject.__init__(self)
697 # we test known-bad values here which cause Gtk-WARNING logs.
698 # Explicitly allow these for this test.
699 with capture_glib_warnings(allow_warnings=True):
700 o = C()
701 self.assertEqual(o.prop_int, 1)
703 o.prop_int = 5
704 self.assertEqual(o.prop_int, 5)
706 o.prop_int = 0
707 self.assertEqual(o.prop_int, 5)
709 o.prop_int = 101
710 self.assertEqual(o.prop_int, 5)
712 self.assertEqual(o.prop_float, 1.1)
714 o.prop_float = 7.75
715 self.assertEqual(o.prop_float, 7.75)
717 o.prop_float = 0.09
718 self.assertEqual(o.prop_float, 7.75)
720 o.prop_float = 10.51
721 self.assertEqual(o.prop_float, 7.75)
723 def test_multiple_instances(self):
724 class C(GObject.GObject):
725 prop = GObject.Property(type=str, default='default')
727 o1 = C()
728 o2 = C()
729 self.assertEqual(o1.prop, 'default')
730 self.assertEqual(o2.prop, 'default')
731 o1.prop = 'value'
732 self.assertEqual(o1.prop, 'value')
733 self.assertEqual(o2.prop, 'default')
735 def test_object_property(self):
736 class PropertyObject(GObject.GObject):
737 obj = GObject.Property(type=GObject.GObject)
739 pobj1 = PropertyObject()
740 obj1_hash = hash(pobj1)
741 pobj2 = PropertyObject()
743 pobj2.obj = pobj1
744 del pobj1
745 pobj1 = pobj2.obj
746 self.assertEqual(hash(pobj1), obj1_hash)
748 def test_object_subclass_property(self):
749 class ObjectSubclass(GObject.GObject):
750 __gtype_name__ = 'ObjectSubclass'
752 class PropertyObjectSubclass(GObject.GObject):
753 obj = GObject.Property(type=ObjectSubclass)
755 PropertyObjectSubclass(obj=ObjectSubclass())
757 def test_property_subclass(self):
758 # test for #470718
759 class A(GObject.GObject):
760 prop1 = GObject.Property(type=int)
762 class B(A):
763 prop2 = GObject.Property(type=int)
765 b = B()
766 b.prop2 = 10
767 self.assertEqual(b.prop2, 10)
768 b.prop1 = 20
769 self.assertEqual(b.prop1, 20)
771 def test_property_subclass_c(self):
772 class A(Regress.TestSubObj):
773 prop1 = GObject.Property(type=int)
775 a = A()
776 a.prop1 = 10
777 self.assertEqual(a.prop1, 10)
779 # also has parent properties
780 a.props.int = 20
781 self.assertEqual(a.props.int, 20)
783 # Some of which are unusable without introspection
784 a.props.list = ("str1", "str2")
785 self.assertEqual(a.props.list, ["str1", "str2"])
787 a.set_property("list", ("str3", "str4"))
788 self.assertEqual(a.props.list, ["str3", "str4"])
790 def test_property_subclass_custom_setter(self):
791 # test for #523352
792 class A(GObject.GObject):
793 def get_first(self):
794 return 'first'
795 first = GObject.Property(type=str, getter=get_first)
797 class B(A):
798 def get_second(self):
799 return 'second'
800 second = GObject.Property(type=str, getter=get_second)
802 a = A()
803 self.assertEqual(a.first, 'first')
804 self.assertRaises(TypeError, setattr, a, 'first', 'foo')
806 b = B()
807 self.assertEqual(b.first, 'first')
808 self.assertRaises(TypeError, setattr, b, 'first', 'foo')
809 self.assertEqual(b.second, 'second')
810 self.assertRaises(TypeError, setattr, b, 'second', 'foo')
812 def test_property_subclass_custom_setter_error(self):
813 try:
814 class A(GObject.GObject):
815 def get_first(self):
816 return 'first'
817 first = GObject.Property(type=str, getter=get_first)
819 def do_get_property(self, pspec):
820 pass
821 except TypeError:
822 pass
823 else:
824 raise AssertionError
826 # Bug 587637.
828 def test_float_min(self):
829 GObject.Property(type=float, minimum=-1)
830 GObject.Property(type=GObject.TYPE_FLOAT, minimum=-1)
831 GObject.Property(type=GObject.TYPE_DOUBLE, minimum=-1)
833 # Bug 644039
834 @unittest.skipUnless(hasattr(sys, "getrefcount"), "no sys.getrefcount")
835 def test_reference_count(self):
836 # We can check directly if an object gets finalized, so we will
837 # observe it indirectly through the refcount of a member object.
839 # We create our dummy object and store its current refcount
840 o = object()
841 rc = sys.getrefcount(o)
843 # We add our object as a member to our newly created object we
844 # want to observe. Its refcount is increased by one.
845 t = PropertyObject(normal="test")
846 t.o = o
847 self.assertEqual(sys.getrefcount(o), rc + 1)
849 # Now we want to ensure we do not leak any references to our
850 # object with properties. If no ref is leaked, then when deleting
851 # the local reference to this object, its reference count shoud
852 # drop to zero, and our dummy object should loose one reference.
853 del t
854 self.assertEqual(sys.getrefcount(o), rc)
856 def test_doc_strings(self):
857 class C(GObject.GObject):
858 foo_blurbed = GObject.Property(type=int, blurb='foo_blurbed doc string')
860 @GObject.Property
861 def foo_getter(self):
862 """foo_getter doc string"""
863 return 0
865 self.assertEqual(C.foo_blurbed.blurb, 'foo_blurbed doc string')
866 self.assertEqual(C.foo_blurbed.__doc__, 'foo_blurbed doc string')
868 self.assertEqual(C.foo_getter.blurb, 'foo_getter doc string')
869 self.assertEqual(C.foo_getter.__doc__, 'foo_getter doc string')
871 def test_python_to_glib_type_mapping(self):
872 tester = GObject.Property()
873 self.assertEqual(tester._type_from_python(int), GObject.TYPE_INT)
874 if PY2:
875 self.assertEqual(tester._type_from_python(long_), GObject.TYPE_LONG)
876 self.assertEqual(tester._type_from_python(bool), GObject.TYPE_BOOLEAN)
877 self.assertEqual(tester._type_from_python(float), GObject.TYPE_DOUBLE)
878 self.assertEqual(tester._type_from_python(str), GObject.TYPE_STRING)
879 self.assertEqual(tester._type_from_python(object), GObject.TYPE_PYOBJECT)
881 self.assertEqual(tester._type_from_python(GObject.GObject), GObject.GObject.__gtype__)
882 self.assertEqual(tester._type_from_python(GObject.GEnum), GObject.GEnum.__gtype__)
883 self.assertEqual(tester._type_from_python(GObject.GFlags), GObject.GFlags.__gtype__)
884 self.assertEqual(tester._type_from_python(GObject.GBoxed), GObject.GBoxed.__gtype__)
885 self.assertEqual(tester._type_from_python(GObject.GInterface), GObject.GInterface.__gtype__)
887 for type_ in [TYPE_NONE, TYPE_INTERFACE, TYPE_CHAR, TYPE_UCHAR,
888 TYPE_INT, TYPE_UINT, TYPE_BOOLEAN, TYPE_LONG,
889 TYPE_ULONG, TYPE_INT64, TYPE_UINT64,
890 TYPE_FLOAT, TYPE_DOUBLE, TYPE_POINTER,
891 TYPE_BOXED, TYPE_PARAM, TYPE_OBJECT, TYPE_STRING,
892 TYPE_PYOBJECT, TYPE_GTYPE, TYPE_STRV]:
893 self.assertEqual(tester._type_from_python(type_), type_)
895 self.assertRaises(TypeError, tester._type_from_python, types.CodeType)
898 class TestInstallProperties(unittest.TestCase):
899 # These tests only test how signalhelper.install_signals works
900 # with the __gsignals__ dict and therefore does not need to use
901 # GObject as a base class because that would automatically call
902 # install_signals within the meta-class.
903 class Base(object):
904 __gproperties__ = {'test': (0, '', '', 0, 0, 0, 0)}
906 class Sub1(Base):
907 pass
909 class Sub2(Base):
910 @GObject.Property(type=int)
911 def sub2test(self):
912 return 123
914 class ClassWithPropertyAndGetterVFunc(object):
915 @GObject.Property(type=int)
916 def sub2test(self):
917 return 123
919 def do_get_property(self, name):
920 return 321
922 class ClassWithPropertyRedefined(object):
923 __gproperties__ = {'test': (0, '', '', 0, 0, 0, 0)}
924 test = GObject.Property(type=int)
926 def setUp(self):
927 self.assertEqual(len(self.Base.__gproperties__), 1)
928 propertyhelper.install_properties(self.Base)
929 self.assertEqual(len(self.Base.__gproperties__), 1)
931 def test_subclass_without_properties_is_not_modified(self):
932 self.assertFalse('__gproperties__' in self.Sub1.__dict__)
933 propertyhelper.install_properties(self.Sub1)
934 self.assertFalse('__gproperties__' in self.Sub1.__dict__)
936 def test_subclass_with_decorator_gets_gproperties_dict(self):
937 # Sub2 has Property instances but will not have a __gproperties__
938 # until install_properties is called
939 self.assertFalse('__gproperties__' in self.Sub2.__dict__)
940 self.assertFalse('do_get_property' in self.Sub2.__dict__)
941 self.assertFalse('do_set_property' in self.Sub2.__dict__)
943 propertyhelper.install_properties(self.Sub2)
944 self.assertTrue('__gproperties__' in self.Sub2.__dict__)
945 self.assertEqual(len(self.Base.__gproperties__), 1)
946 self.assertEqual(len(self.Sub2.__gproperties__), 1)
947 self.assertTrue('sub2test' in self.Sub2.__gproperties__)
949 # get/set vfuncs should have been added
950 self.assertTrue('do_get_property' in self.Sub2.__dict__)
951 self.assertTrue('do_set_property' in self.Sub2.__dict__)
953 def test_object_with_property_and_do_get_property_vfunc_raises(self):
954 self.assertRaises(TypeError, propertyhelper.install_properties,
955 self.ClassWithPropertyAndGetterVFunc)
957 def test_same_name_property_definitions_raises(self):
958 self.assertRaises(ValueError, propertyhelper.install_properties,
959 self.ClassWithPropertyRedefined)
962 class CPropertiesTestBase(object):
963 # Tests for properties implemented in C not Python.
965 def setUp(self):
966 self.obj = GIMarshallingTests.PropertiesObject()
968 def get_prop(self, obj, name):
969 raise NotImplementedError
971 def set_prop(self, obj, name, value):
972 raise NotImplementedError
974 # https://bugzilla.gnome.org/show_bug.cgi?id=780652
975 @unittest.skipUnless(
976 "some_flags" in dir(GIMarshallingTests.PropertiesObject.props),
977 "tool old gi")
978 def test_flags(self):
979 self.assertEqual(
980 self.get_prop(self.obj, 'some-flags'),
981 GIMarshallingTests.Flags.VALUE1)
982 self.set_prop(self.obj, 'some-flags', GIMarshallingTests.Flags.VALUE2)
983 self.assertEqual(self.get_prop(self.obj, 'some-flags'),
984 GIMarshallingTests.Flags.VALUE2)
986 obj = GIMarshallingTests.PropertiesObject(
987 some_flags=GIMarshallingTests.Flags.VALUE3)
988 self.assertEqual(self.get_prop(obj, 'some-flags'),
989 GIMarshallingTests.Flags.VALUE3)
991 # https://bugzilla.gnome.org/show_bug.cgi?id=780652
992 @unittest.skipUnless(
993 "some_enum" in dir(GIMarshallingTests.PropertiesObject.props),
994 "tool old gi")
995 def test_enum(self):
996 self.assertEqual(
997 self.get_prop(self.obj, 'some-enum'),
998 GIMarshallingTests.GEnum.VALUE1)
999 self.set_prop(self.obj, 'some-enum', GIMarshallingTests.GEnum.VALUE2)
1000 self.assertEqual(self.get_prop(self.obj, 'some-enum'),
1001 GIMarshallingTests.GEnum.VALUE2)
1003 obj = GIMarshallingTests.PropertiesObject(
1004 some_enum=GIMarshallingTests.GEnum.VALUE3)
1005 self.assertEqual(self.get_prop(obj, 'some-enum'),
1006 GIMarshallingTests.GEnum.VALUE3)
1008 def test_boolean(self):
1009 self.assertEqual(self.get_prop(self.obj, 'some-boolean'), False)
1010 self.set_prop(self.obj, 'some-boolean', True)
1011 self.assertEqual(self.get_prop(self.obj, 'some-boolean'), True)
1013 obj = GIMarshallingTests.PropertiesObject(some_boolean=True)
1014 self.assertEqual(self.get_prop(obj, 'some-boolean'), True)
1016 def test_char(self):
1017 self.assertEqual(self.get_prop(self.obj, 'some-char'), 0)
1018 self.set_prop(self.obj, 'some-char', GLib.MAXINT8)
1019 self.assertEqual(self.get_prop(self.obj, 'some-char'), GLib.MAXINT8)
1021 obj = GIMarshallingTests.PropertiesObject(some_char=-42)
1022 self.assertEqual(self.get_prop(obj, 'some-char'), -42)
1024 with pytest.raises(OverflowError):
1025 self.set_prop(obj, 'some-char', GLib.MAXINT8 + 1)
1026 with pytest.raises(OverflowError):
1027 self.set_prop(obj, 'some-char', GLib.MININT8 - 1)
1029 self.set_prop(obj, 'some-char', b"\x44")
1030 assert self.get_prop(obj, 'some-char') == 0x44
1032 self.set_prop(obj, 'some-char', b"\xff")
1033 assert self.get_prop(obj, 'some-char') == -1
1035 obj = GIMarshallingTests.PropertiesObject(some_char=u"\x7f")
1036 assert self.get_prop(obj, 'some-char') == 0x7f
1038 with pytest.raises(TypeError):
1039 GIMarshallingTests.PropertiesObject(some_char=u"€")
1041 with pytest.raises(TypeError):
1042 GIMarshallingTests.PropertiesObject(some_char=u"\ud83d")
1044 def test_uchar(self):
1045 self.assertEqual(self.get_prop(self.obj, 'some-uchar'), 0)
1046 self.set_prop(self.obj, 'some-uchar', GLib.MAXUINT8)
1047 self.assertEqual(self.get_prop(self.obj, 'some-uchar'), GLib.MAXUINT8)
1049 obj = GIMarshallingTests.PropertiesObject(some_uchar=42)
1050 self.assertEqual(self.get_prop(obj, 'some-uchar'), 42)
1052 with pytest.raises(OverflowError):
1053 self.set_prop(obj, 'some-uchar', GLib.MAXUINT8 + 1)
1054 with pytest.raises(OverflowError):
1055 self.set_prop(obj, 'some-uchar', -1)
1057 self.set_prop(obj, 'some-uchar', b"\x57")
1058 assert self.get_prop(obj, 'some-uchar') == 0x57
1060 self.set_prop(obj, 'some-uchar', b"\xff")
1061 assert self.get_prop(obj, 'some-uchar') == 255
1063 obj = GIMarshallingTests.PropertiesObject(some_uchar=u"\x7f")
1064 assert self.get_prop(obj, 'some-uchar') == 127
1066 with pytest.raises(TypeError):
1067 GIMarshallingTests.PropertiesObject(some_uchar=u"\x80")
1069 with pytest.raises(TypeError):
1070 GIMarshallingTests.PropertiesObject(some_uchar=u"\ud83d")
1072 def test_int(self):
1073 self.assertEqual(self.get_prop(self.obj, 'some_int'), 0)
1074 self.set_prop(self.obj, 'some-int', GLib.MAXINT)
1075 self.assertEqual(self.get_prop(self.obj, 'some_int'), GLib.MAXINT)
1077 obj = GIMarshallingTests.PropertiesObject(some_int=-42)
1078 self.assertEqual(self.get_prop(obj, 'some-int'), -42)
1080 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-int', 'foo')
1081 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-int', None)
1083 self.assertEqual(self.get_prop(obj, 'some-int'), -42)
1085 def test_uint(self):
1086 self.assertEqual(self.get_prop(self.obj, 'some_uint'), 0)
1087 self.set_prop(self.obj, 'some-uint', GLib.MAXUINT)
1088 self.assertEqual(self.get_prop(self.obj, 'some_uint'), GLib.MAXUINT)
1090 obj = GIMarshallingTests.PropertiesObject(some_uint=42)
1091 self.assertEqual(self.get_prop(obj, 'some-uint'), 42)
1093 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-uint', 'foo')
1094 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-uint', None)
1096 self.assertEqual(self.get_prop(obj, 'some-uint'), 42)
1098 def test_long(self):
1099 self.assertEqual(self.get_prop(self.obj, 'some_long'), 0)
1100 self.set_prop(self.obj, 'some-long', GLib.MAXLONG)
1101 self.assertEqual(self.get_prop(self.obj, 'some_long'), GLib.MAXLONG)
1103 obj = GIMarshallingTests.PropertiesObject(some_long=-42)
1104 self.assertEqual(self.get_prop(obj, 'some-long'), -42)
1106 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-long', 'foo')
1107 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-long', None)
1109 self.assertEqual(self.get_prop(obj, 'some-long'), -42)
1111 def test_ulong(self):
1112 self.assertEqual(self.get_prop(self.obj, 'some_ulong'), 0)
1113 self.set_prop(self.obj, 'some-ulong', GLib.MAXULONG)
1114 self.assertEqual(self.get_prop(self.obj, 'some_ulong'), GLib.MAXULONG)
1116 obj = GIMarshallingTests.PropertiesObject(some_ulong=42)
1117 self.assertEqual(self.get_prop(obj, 'some-ulong'), 42)
1119 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-ulong', 'foo')
1120 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-ulong', None)
1122 self.assertEqual(self.get_prop(obj, 'some-ulong'), 42)
1124 def test_int64(self):
1125 self.assertEqual(self.get_prop(self.obj, 'some-int64'), 0)
1126 self.set_prop(self.obj, 'some-int64', GLib.MAXINT64)
1127 self.assertEqual(self.get_prop(self.obj, 'some-int64'), GLib.MAXINT64)
1129 obj = GIMarshallingTests.PropertiesObject(some_int64=-4200000000000000)
1130 self.assertEqual(self.get_prop(obj, 'some-int64'), -4200000000000000)
1132 def test_uint64(self):
1133 self.assertEqual(self.get_prop(self.obj, 'some-uint64'), 0)
1134 self.set_prop(self.obj, 'some-uint64', GLib.MAXUINT64)
1135 self.assertEqual(self.get_prop(self.obj, 'some-uint64'), GLib.MAXUINT64)
1137 obj = GIMarshallingTests.PropertiesObject(some_uint64=4200000000000000)
1138 self.assertEqual(self.get_prop(obj, 'some-uint64'), 4200000000000000)
1140 def test_float(self):
1141 self.assertEqual(self.get_prop(self.obj, 'some-float'), 0)
1142 self.set_prop(self.obj, 'some-float', GLib.MAXFLOAT)
1143 self.assertEqual(self.get_prop(self.obj, 'some-float'), GLib.MAXFLOAT)
1145 obj = GIMarshallingTests.PropertiesObject(some_float=42.42)
1146 self.assertAlmostEqual(self.get_prop(obj, 'some-float'), 42.42, places=4)
1148 obj = GIMarshallingTests.PropertiesObject(some_float=42)
1149 self.assertAlmostEqual(self.get_prop(obj, 'some-float'), 42.0, places=4)
1151 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-float', 'foo')
1152 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-float', None)
1154 self.assertAlmostEqual(self.get_prop(obj, 'some-float'), 42.0, places=4)
1156 def test_double(self):
1157 self.assertEqual(self.get_prop(self.obj, 'some-double'), 0)
1158 self.set_prop(self.obj, 'some-double', GLib.MAXDOUBLE)
1159 self.assertEqual(self.get_prop(self.obj, 'some-double'), GLib.MAXDOUBLE)
1161 obj = GIMarshallingTests.PropertiesObject(some_double=42.42)
1162 self.assertAlmostEqual(self.get_prop(obj, 'some-double'), 42.42)
1164 obj = GIMarshallingTests.PropertiesObject(some_double=42)
1165 self.assertAlmostEqual(self.get_prop(obj, 'some-double'), 42.0)
1167 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-double', 'foo')
1168 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-double', None)
1170 self.assertAlmostEqual(self.get_prop(obj, 'some-double'), 42.0)
1172 def test_strv(self):
1173 self.assertEqual(self.get_prop(self.obj, 'some-strv'), [])
1174 self.set_prop(self.obj, 'some-strv', ['hello', 'world'])
1175 self.assertEqual(self.get_prop(self.obj, 'some-strv'), ['hello', 'world'])
1177 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-strv', 1)
1178 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-strv', 'foo')
1179 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-strv', [1, 2])
1180 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-strv', ['foo', 1])
1182 self.assertEqual(self.get_prop(self.obj, 'some-strv'), ['hello', 'world'])
1184 obj = GIMarshallingTests.PropertiesObject(some_strv=['hello', 'world'])
1185 self.assertEqual(self.get_prop(obj, 'some-strv'), ['hello', 'world'])
1187 # unicode on py2
1188 obj = GIMarshallingTests.PropertiesObject(some_strv=[u'foo'])
1189 self.assertEqual(self.get_prop(obj, 'some-strv'), [u'foo'])
1190 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-strv',
1191 [u'foo', 1])
1193 def test_boxed_struct(self):
1194 self.assertEqual(self.get_prop(self.obj, 'some-boxed-struct'), None)
1196 class GStrv(list):
1197 __gtype__ = GObject.TYPE_STRV
1199 struct1 = GIMarshallingTests.BoxedStruct()
1200 struct1.long_ = 1
1202 self.set_prop(self.obj, 'some-boxed-struct', struct1)
1203 self.assertEqual(self.get_prop(self.obj, 'some-boxed-struct').long_, 1)
1204 self.assertEqual(self.obj.some_boxed_struct.long_, 1)
1206 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-boxed-struct', 1)
1207 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-boxed-struct', 'foo')
1209 obj = GIMarshallingTests.PropertiesObject(some_boxed_struct=struct1)
1210 self.assertEqual(self.get_prop(obj, 'some-boxed-struct').long_, 1)
1212 def test_boxed_glist(self):
1213 self.assertEqual(self.get_prop(self.obj, 'some-boxed-glist'), [])
1215 list_ = [GLib.MININT, 42, GLib.MAXINT]
1216 self.set_prop(self.obj, 'some-boxed-glist', list_)
1217 self.assertEqual(self.get_prop(self.obj, 'some-boxed-glist'), list_)
1218 self.set_prop(self.obj, 'some-boxed-glist', [])
1219 self.assertEqual(self.get_prop(self.obj, 'some-boxed-glist'), [])
1221 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-boxed-glist', 1)
1222 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-boxed-glist', 'foo')
1223 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-boxed-glist', ['a'])
1225 def test_annotated_glist(self):
1226 obj = Regress.TestObj()
1227 self.assertEqual(self.get_prop(obj, 'list'), [])
1229 self.set_prop(obj, 'list', ['1', '2', '3'])
1230 self.assertTrue(isinstance(self.get_prop(obj, 'list'), list))
1231 self.assertEqual(self.get_prop(obj, 'list'), ['1', '2', '3'])
1233 @unittest.expectedFailure
1234 def test_boxed_glist_ctor(self):
1235 list_ = [GLib.MININT, 42, GLib.MAXINT]
1236 obj = GIMarshallingTests.PropertiesObject(some_boxed_glist=list_)
1237 self.assertEqual(self.get_prop(obj, 'some-boxed-glist'), list_)
1239 def test_variant(self):
1240 self.assertEqual(self.get_prop(self.obj, 'some-variant'), None)
1242 self.set_prop(self.obj, 'some-variant', GLib.Variant('o', '/myobj'))
1243 self.assertEqual(self.get_prop(self.obj, 'some-variant').get_type_string(), 'o')
1244 self.assertEqual(self.get_prop(self.obj, 'some-variant').print_(False), "'/myobj'")
1246 self.set_prop(self.obj, 'some-variant', None)
1247 self.assertEqual(self.get_prop(self.obj, 'some-variant'), None)
1249 obj = GIMarshallingTests.PropertiesObject(some_variant=GLib.Variant('b', True))
1250 self.assertEqual(self.get_prop(obj, 'some-variant').get_type_string(), 'b')
1251 self.assertEqual(self.get_prop(obj, 'some-variant').get_boolean(), True)
1253 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-variant', 'foo')
1254 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-variant', 23)
1256 self.assertEqual(self.get_prop(obj, 'some-variant').get_type_string(), 'b')
1257 self.assertEqual(self.get_prop(obj, 'some-variant').get_boolean(), True)
1259 def test_setting_several_properties(self):
1260 obj = GIMarshallingTests.PropertiesObject()
1261 obj.set_properties(some_uchar=54, some_int=42)
1262 self.assertEqual(42, self.get_prop(obj, 'some-int'))
1263 self.assertEqual(54, self.get_prop(obj, 'some-uchar'))
1265 def test_gtype(self):
1266 obj = Regress.TestObj()
1267 self.assertEqual(self.get_prop(obj, 'gtype'), GObject.TYPE_INVALID)
1268 self.set_prop(obj, 'gtype', int)
1269 self.assertEqual(self.get_prop(obj, 'gtype'), GObject.TYPE_INT)
1271 obj = Regress.TestObj(gtype=int)
1272 self.assertEqual(self.get_prop(obj, 'gtype'), GObject.TYPE_INT)
1273 self.set_prop(obj, 'gtype', str)
1274 self.assertEqual(self.get_prop(obj, 'gtype'), GObject.TYPE_STRING)
1276 def test_hash_table(self):
1277 obj = Regress.TestObj()
1278 self.assertEqual(self.get_prop(obj, 'hash-table'), None)
1280 self.set_prop(obj, 'hash-table', {'mec': 56})
1281 self.assertTrue(isinstance(self.get_prop(obj, 'hash-table'), dict))
1282 self.assertEqual(list(self.get_prop(obj, 'hash-table').items())[0],
1283 ('mec', 56))
1285 def test_parent_class(self):
1286 class A(Regress.TestObj):
1287 prop1 = GObject.Property(type=int)
1289 a = A()
1290 self.set_prop(a, 'int', 20)
1291 self.assertEqual(self.get_prop(a, 'int'), 20)
1293 # test parent property which needs introspection
1294 self.set_prop(a, 'list', ("str1", "str2"))
1295 self.assertEqual(self.get_prop(a, 'list'), ["str1", "str2"])
1297 def test_held_object_ref_count_getter(self):
1298 holder = GIMarshallingTests.PropertiesObject()
1299 held = GObject.Object()
1301 self.assertEqual(holder.__grefcount__, 1)
1302 self.assertEqual(held.__grefcount__, 1)
1304 self.set_prop(holder, 'some-object', held)
1305 self.assertEqual(holder.__grefcount__, 1)
1307 initial_ref_count = held.__grefcount__
1308 self.get_prop(holder, 'some-object')
1309 gc.collect()
1310 self.assertEqual(held.__grefcount__, initial_ref_count)
1312 def test_held_object_ref_count_setter(self):
1313 holder = GIMarshallingTests.PropertiesObject()
1314 held = GObject.Object()
1316 self.assertEqual(holder.__grefcount__, 1)
1317 self.assertEqual(held.__grefcount__, 1)
1319 # Setting property should only increase ref count by 1
1320 self.set_prop(holder, 'some-object', held)
1321 self.assertEqual(holder.__grefcount__, 1)
1322 self.assertEqual(held.__grefcount__, 2)
1324 # Clearing should pull it back down
1325 self.set_prop(holder, 'some-object', None)
1326 self.assertEqual(held.__grefcount__, 1)
1328 def test_set_object_property_to_invalid_type(self):
1329 obj = GIMarshallingTests.PropertiesObject()
1330 self.assertRaises(TypeError, self.set_prop, obj, 'some-object', 'not_an_object')
1333 class TestCPropsAccessor(CPropertiesTestBase, unittest.TestCase):
1334 # C property tests using the "props" accessor.
1335 def get_prop(self, obj, name):
1336 return getattr(obj.props, name.replace('-', '_'))
1338 def set_prop(self, obj, name, value):
1339 setattr(obj.props, name.replace('-', '_'), value)
1341 def test_props_accessor_dir(self):
1342 # Test class
1343 props = dir(GIMarshallingTests.PropertiesObject.props)
1344 self.assertTrue('some_float' in props)
1345 self.assertTrue('some_double' in props)
1346 self.assertTrue('some_variant' in props)
1348 # Test instance
1349 obj = GIMarshallingTests.PropertiesObject()
1350 props = dir(obj.props)
1351 self.assertTrue('some_float' in props)
1352 self.assertTrue('some_double' in props)
1353 self.assertTrue('some_variant' in props)
1355 def test_param_spec_dir(self):
1356 attrs = dir(GIMarshallingTests.PropertiesObject.props.some_float)
1357 self.assertTrue('name' in attrs)
1358 self.assertTrue('nick' in attrs)
1359 self.assertTrue('blurb' in attrs)
1360 self.assertTrue('flags' in attrs)
1361 self.assertTrue('default_value' in attrs)
1362 self.assertTrue('minimum' in attrs)
1363 self.assertTrue('maximum' in attrs)
1366 class TestCGetPropertyMethod(CPropertiesTestBase, unittest.TestCase):
1367 # C property tests using the "props" accessor.
1368 def get_prop(self, obj, name):
1369 return obj.get_property(name)
1371 def set_prop(self, obj, name, value):
1372 obj.set_property(name, value)