10 from gi.repository import GObject
11 from gi.repository.GObject import ParamFlags, GType, new
12 from gi.repository.GObject import \
13 TYPE_INT, TYPE_UINT, TYPE_LONG, TYPE_ULONG, TYPE_INT64, \
14 TYPE_UINT64, TYPE_GTYPE, TYPE_INVALID, TYPE_NONE, TYPE_STRV, \
15 TYPE_INTERFACE, TYPE_CHAR, TYPE_UCHAR, TYPE_BOOLEAN, TYPE_FLOAT, \
16 TYPE_DOUBLE, TYPE_POINTER, TYPE_BOXED, TYPE_PARAM, TYPE_OBJECT, \
17 TYPE_STRING, TYPE_PYOBJECT, TYPE_VARIANT
19 from gi.repository.GLib import \
20 MININT, MAXINT, MAXUINT, MINLONG, MAXLONG, MAXULONG, \
21 MAXUINT64, MAXINT64, MININT64
23 from gi.repository import Gio
24 from gi.repository import GLib
25 gi.require_version('GIMarshallingTests', '1.0')
26 from gi.repository import GIMarshallingTests
27 from gi import _propertyhelper as propertyhelper
30 gi.require_version('Regress', '1.0')
31 from gi.repository import Regress
33 except (ValueError, ImportError):
36 if sys.version_info < (3, 0):
37 TEST_UTF8 = "\xe2\x99\xa5"
38 UNICODE_UTF8 = unicode(TEST_UTF8, 'UTF-8')
41 UNICODE_UTF8 = TEST_UTF8
43 from compathelper import _long
46 class PropertyObject(GObject.GObject):
47 normal = GObject.Property(type=str)
48 construct = GObject.Property(
50 flags=ParamFlags.READABLE | ParamFlags.WRITABLE | ParamFlags.CONSTRUCT,
53 construct_only = GObject.Property(
55 flags=ParamFlags.READABLE | ParamFlags.WRITABLE | ParamFlags.CONSTRUCT_ONLY)
57 uint64 = GObject.Property(
59 flags=ParamFlags.READABLE | ParamFlags.WRITABLE | ParamFlags.CONSTRUCT)
61 enum = GObject.Property(
62 type=Gio.SocketType, default=Gio.SocketType.STREAM)
64 boxed = GObject.Property(
66 flags=ParamFlags.READABLE | ParamFlags.WRITABLE | ParamFlags.CONSTRUCT)
68 flags = GObject.Property(
69 type=GIMarshallingTests.Flags,
70 flags=ParamFlags.READABLE | ParamFlags.WRITABLE | ParamFlags.CONSTRUCT,
71 default=GIMarshallingTests.Flags.VALUE1)
73 gtype = GObject.Property(
75 flags=ParamFlags.READABLE | ParamFlags.WRITABLE | ParamFlags.CONSTRUCT)
77 strings = GObject.Property(
79 flags=ParamFlags.READABLE | ParamFlags.WRITABLE | ParamFlags.CONSTRUCT)
81 variant = GObject.Property(
83 flags=ParamFlags.READABLE | ParamFlags.WRITABLE | ParamFlags.CONSTRUCT)
85 variant_def = GObject.Property(
87 flags=ParamFlags.READABLE | ParamFlags.WRITABLE | ParamFlags.CONSTRUCT,
88 default=GLib.Variant('i', 42))
90 interface = GObject.Property(
92 flags=ParamFlags.READABLE | ParamFlags.WRITABLE | ParamFlags.CONSTRUCT)
96 class PropertyInheritanceObject(Regress.TestObj):
97 # override property from the base class, with a different type
98 string = GObject.Property(type=int)
100 # a property entirely defined at the Python level
101 python_prop = GObject.Property(type=str)
103 class PropertySubClassObject(PropertyInheritanceObject):
104 # override property from the base class, with a different type
105 python_prop = GObject.Property(type=int)
108 @unittest.skipUnless(has_regress, 'Missing Regress typelib')
109 class TestPropertyInheritanceObject(unittest.TestCase):
110 def test_override_gi_property(self):
111 self.assertNotEqual(Regress.TestObj.props.string.value_type,
112 PropertyInheritanceObject.props.string.value_type)
113 obj = PropertyInheritanceObject()
114 self.assertEqual(type(obj.props.string), int)
116 self.assertEqual(obj.props.string, 4)
118 def test_override_python_property(self):
119 obj = PropertySubClassObject()
120 self.assertEqual(type(obj.props.python_prop), int)
121 obj.props.python_prop = 5
122 self.assertEqual(obj.props.python_prop, 5)
125 class TestPropertyObject(unittest.TestCase):
126 def test_get_set(self):
127 obj = PropertyObject()
128 obj.props.normal = "value"
129 self.assertEqual(obj.props.normal, "value")
131 def test_hasattr_on_object(self):
132 obj = PropertyObject()
133 self.assertTrue(hasattr(obj.props, "normal"))
135 def test_hasattr_on_class(self):
136 self.assertTrue(hasattr(PropertyObject.props, "normal"))
138 def test_set_on_class(self):
140 obj.props.normal = "foobar"
142 self.assertRaises(TypeError, set, PropertyObject)
144 def test_iteration(self):
145 for obj in (PropertyObject.props, PropertyObject().props):
149 self.assertEqual(gtype.parent.name, 'GParam')
150 names.append(pspec.name)
153 self.assertEqual(names, ['boxed',
166 def test_normal(self):
167 obj = new(PropertyObject, normal="123")
168 self.assertEqual(obj.props.normal, "123")
169 obj.set_property('normal', '456')
170 self.assertEqual(obj.props.normal, "456")
171 obj.props.normal = '789'
172 self.assertEqual(obj.props.normal, "789")
174 def test_construct(self):
175 obj = new(PropertyObject, construct="123")
176 self.assertEqual(obj.props.construct, "123")
177 obj.set_property('construct', '456')
178 self.assertEqual(obj.props.construct, "456")
179 obj.props.construct = '789'
180 self.assertEqual(obj.props.construct, "789")
183 obj = new(PropertyObject, construct_only=UNICODE_UTF8)
184 self.assertEqual(obj.props.construct_only, TEST_UTF8)
185 obj.set_property('construct', UNICODE_UTF8)
186 self.assertEqual(obj.props.construct, TEST_UTF8)
187 obj.props.normal = UNICODE_UTF8
188 self.assertEqual(obj.props.normal, TEST_UTF8)
190 def test_int_to_str(self):
191 obj = new(PropertyObject, construct_only=1)
192 self.assertEqual(obj.props.construct_only, '1')
193 obj.set_property('construct', '2')
194 self.assertEqual(obj.props.construct, '2')
196 self.assertEqual(obj.props.normal, '3')
198 def test_construct_only(self):
199 obj = new(PropertyObject, construct_only="123")
200 self.assertEqual(obj.props.construct_only, "123")
201 self.assertRaises(TypeError,
202 setattr, obj.props, 'construct_only', '456')
203 self.assertRaises(TypeError,
204 obj.set_property, 'construct-only', '456')
206 def test_uint64(self):
207 obj = new(PropertyObject)
208 self.assertEqual(obj.props.uint64, 0)
209 obj.props.uint64 = _long(1)
210 self.assertEqual(obj.props.uint64, _long(1))
212 self.assertEqual(obj.props.uint64, _long(1))
214 self.assertRaises((TypeError, OverflowError), obj.set_property, "uint64", _long(-1))
215 self.assertRaises((TypeError, OverflowError), obj.set_property, "uint64", -1)
217 def test_uint64_default_value(self):
219 class TimeControl(GObject.GObject):
221 'time': (TYPE_UINT64, 'Time', 'Time',
222 _long(0), (1 << 64) - 1, _long(0),
225 except OverflowError:
226 (etype, ex) = sys.exc_info()[2:]
230 obj = new(PropertyObject)
231 self.assertEqual(obj.props.enum, Gio.SocketType.STREAM)
232 self.assertEqual(obj.enum, Gio.SocketType.STREAM)
233 obj.enum = Gio.SocketType.DATAGRAM
234 self.assertEqual(obj.props.enum, Gio.SocketType.DATAGRAM)
235 self.assertEqual(obj.enum, Gio.SocketType.DATAGRAM)
236 obj.props.enum = Gio.SocketType.STREAM
237 self.assertEqual(obj.props.enum, Gio.SocketType.STREAM)
238 self.assertEqual(obj.enum, Gio.SocketType.STREAM)
240 self.assertEqual(obj.props.enum, Gio.SocketType.DATAGRAM)
241 self.assertEqual(obj.enum, Gio.SocketType.DATAGRAM)
243 self.assertEqual(obj.props.enum, Gio.SocketType.STREAM)
244 self.assertEqual(obj.enum, Gio.SocketType.STREAM)
246 self.assertRaises(TypeError, setattr, obj, 'enum', 'foo')
247 self.assertRaises(TypeError, setattr, obj, 'enum', object())
249 self.assertRaises(TypeError, GObject.Property, type=Gio.SocketType)
250 self.assertRaises(TypeError, GObject.Property, type=Gio.SocketType,
251 default=Gio.SocketProtocol.TCP)
252 self.assertRaises(TypeError, GObject.Property, type=Gio.SocketType,
254 self.assertRaises(TypeError, GObject.Property, type=Gio.SocketType,
257 def test_flags(self):
258 obj = new(PropertyObject)
259 self.assertEqual(obj.props.flags, GIMarshallingTests.Flags.VALUE1)
260 self.assertEqual(obj.flags, GIMarshallingTests.Flags.VALUE1)
262 obj.flags = GIMarshallingTests.Flags.VALUE2 | GIMarshallingTests.Flags.VALUE3
263 self.assertEqual(obj.props.flags, GIMarshallingTests.Flags.VALUE2 | GIMarshallingTests.Flags.VALUE3)
264 self.assertEqual(obj.flags, GIMarshallingTests.Flags.VALUE2 | GIMarshallingTests.Flags.VALUE3)
266 self.assertRaises(TypeError, setattr, obj, 'flags', 'foo')
267 self.assertRaises(TypeError, setattr, obj, 'flags', object())
268 self.assertRaises(TypeError, setattr, obj, 'flags', None)
270 self.assertRaises(TypeError, GObject.Property,
271 type=GIMarshallingTests.Flags, default='foo')
272 self.assertRaises(TypeError, GObject.Property,
273 type=GIMarshallingTests.Flags, default=object())
274 self.assertRaises(TypeError, GObject.Property,
275 type=GIMarshallingTests.Flags, default=None)
277 def test_gtype(self):
278 obj = new(PropertyObject)
280 self.assertEqual(obj.props.gtype, TYPE_NONE)
281 self.assertEqual(obj.gtype, TYPE_NONE)
283 obj.gtype = TYPE_UINT64
284 self.assertEqual(obj.props.gtype, TYPE_UINT64)
285 self.assertEqual(obj.gtype, TYPE_UINT64)
287 obj.gtype = TYPE_INVALID
288 self.assertEqual(obj.props.gtype, TYPE_INVALID)
289 self.assertEqual(obj.gtype, TYPE_INVALID)
291 # GType parameters do not support defaults in GLib
292 self.assertRaises(TypeError, GObject.Property, type=TYPE_GTYPE,
296 self.assertRaises(TypeError, setattr, obj, 'gtype', 'foo')
297 self.assertRaises(TypeError, setattr, obj, 'gtype', object())
299 self.assertRaises(TypeError, GObject.Property, type=TYPE_GTYPE,
301 self.assertRaises(TypeError, GObject.Property, type=TYPE_GTYPE,
305 obj = new(PropertyObject, gtype=TYPE_UINT)
306 self.assertEqual(obj.props.gtype, TYPE_UINT)
307 self.assertEqual(obj.gtype, TYPE_UINT)
309 def test_boxed(self):
310 obj = new(PropertyObject)
312 regex = GLib.Regex.new('[a-z]*', 0, 0)
313 obj.props.boxed = regex
314 self.assertEqual(obj.props.boxed.get_pattern(), '[a-z]*')
315 self.assertEqual(obj.boxed.get_pattern(), '[a-z]*')
317 self.assertRaises(TypeError, setattr, obj, 'boxed', 'foo')
318 self.assertRaises(TypeError, setattr, obj, 'boxed', object())
320 def test_strings(self):
321 obj = new(PropertyObject)
323 # Should work with actual GStrv objects as well as
324 # Python string lists
326 __gtype__ = GObject.TYPE_STRV
328 self.assertEqual(obj.props.strings, GStrv([]))
329 self.assertEqual(obj.strings, GStrv([]))
330 self.assertEqual(obj.props.strings, [])
331 self.assertEqual(obj.strings, [])
333 obj.strings = ['hello', 'world']
334 self.assertEqual(obj.props.strings, ['hello', 'world'])
335 self.assertEqual(obj.strings, ['hello', 'world'])
337 obj.strings = GStrv(['hello', 'world'])
338 self.assertEqual(obj.props.strings, GStrv(['hello', 'world']))
339 self.assertEqual(obj.strings, GStrv(['hello', 'world']))
342 self.assertEqual(obj.strings, [])
343 obj.strings = GStrv([])
344 self.assertEqual(obj.strings, GStrv([]))
346 p = GObject.Property(type=TYPE_STRV, default=['hello', '1'])
347 self.assertEqual(p.default, ['hello', '1'])
348 self.assertEqual(p.type, TYPE_STRV)
349 p = GObject.Property(type=TYPE_STRV, default=GStrv(['hello', '1']))
350 self.assertEqual(p.default, ['hello', '1'])
351 self.assertEqual(p.type, TYPE_STRV)
354 obj = new(PropertyObject, strings=['hello', 'world'])
355 self.assertEqual(obj.props.strings, ['hello', 'world'])
356 self.assertEqual(obj.strings, ['hello', 'world'])
359 self.assertRaises(TypeError, setattr, obj, 'strings', 1)
360 self.assertRaises(TypeError, setattr, obj, 'strings', 'foo')
361 self.assertRaises(TypeError, setattr, obj, 'strings', ['foo', 1])
363 self.assertRaises(TypeError, GObject.Property, type=TYPE_STRV,
365 self.assertRaises(TypeError, GObject.Property, type=TYPE_STRV,
367 self.assertRaises(TypeError, GObject.Property, type=TYPE_STRV,
368 default=['hello', 1])
370 def test_variant(self):
371 obj = new(PropertyObject)
373 self.assertEqual(obj.props.variant, None)
374 self.assertEqual(obj.variant, None)
376 obj.variant = GLib.Variant('s', 'hello')
377 self.assertEqual(obj.variant.print_(True), "'hello'")
379 obj.variant = GLib.Variant('b', True)
380 self.assertEqual(obj.variant.print_(True), "true")
382 obj.props.variant = GLib.Variant('y', 2)
383 self.assertEqual(obj.variant.print_(True), "byte 0x02")
386 self.assertEqual(obj.variant, None)
389 obj = new(PropertyObject, variant=GLib.Variant('u', 5))
390 self.assertEqual(obj.props.variant.print_(True), 'uint32 5')
392 GObject.Property(type=TYPE_VARIANT, default=GLib.Variant('i', 1))
395 self.assertRaises(TypeError, setattr, obj, 'variant', 'foo')
396 self.assertRaises(TypeError, setattr, obj, 'variant', 42)
398 self.assertRaises(TypeError, GObject.Property, type=TYPE_VARIANT,
400 self.assertRaises(TypeError, GObject.Property, type=TYPE_VARIANT,
403 def test_variant_default(self):
404 obj = new(PropertyObject)
406 self.assertEqual(obj.props.variant_def.print_(True), '42')
407 self.assertEqual(obj.variant_def.print_(True), '42')
409 obj.props.variant_def = GLib.Variant('y', 2)
410 self.assertEqual(obj.variant_def.print_(True), "byte 0x02")
413 obj = new(PropertyObject, variant_def=GLib.Variant('u', 5))
414 self.assertEqual(obj.props.variant_def.print_(True), 'uint32 5')
416 def test_interface(self):
417 obj = new(PropertyObject)
419 file = Gio.File.new_for_path('/some/path')
420 obj.props.interface = file
421 self.assertEqual(obj.props.interface.get_path(), '/some/path')
422 self.assertEqual(obj.interface.get_path(), '/some/path')
424 self.assertRaises(TypeError, setattr, obj, 'interface', 'foo')
425 self.assertRaises(TypeError, setattr, obj, 'interface', object())
427 def test_range(self):
430 return 2 ** ((8 * struct.calcsize(c)) - 1) - 1
433 return 2 ** (8 * struct.calcsize(c)) - 1
439 minlong = -maxlong - 1
442 minint64 = -maxint64 - 1
443 maxuint64 = umax('Q')
445 types_ = dict(int=(TYPE_INT, minint, maxint),
446 uint=(TYPE_UINT, 0, maxuint),
447 long=(TYPE_LONG, minlong, maxlong),
448 ulong=(TYPE_ULONG, 0, maxulong),
449 int64=(TYPE_INT64, minint64, maxint64),
450 uint64=(TYPE_UINT64, 0, maxuint64))
452 def build_gproperties(types_):
454 for key, (gtype, min, max) in types_.items():
455 d[key] = (gtype, 'blurb', 'desc', min, max, 0,
456 ParamFlags.READABLE | ParamFlags.WRITABLE)
459 class RangeCheck(GObject.GObject):
460 __gproperties__ = build_gproperties(types_)
464 GObject.GObject.__init__(self)
466 def do_set_property(self, pspec, value):
467 self.values[pspec.name] = value
469 def do_get_property(self, pspec):
470 return self.values.get(pspec.name, pspec.default_value)
472 self.assertEqual(RangeCheck.props.int.minimum, minint)
473 self.assertEqual(RangeCheck.props.int.maximum, maxint)
474 self.assertEqual(RangeCheck.props.uint.minimum, 0)
475 self.assertEqual(RangeCheck.props.uint.maximum, maxuint)
476 self.assertEqual(RangeCheck.props.long.minimum, minlong)
477 self.assertEqual(RangeCheck.props.long.maximum, maxlong)
478 self.assertEqual(RangeCheck.props.ulong.minimum, 0)
479 self.assertEqual(RangeCheck.props.ulong.maximum, maxulong)
480 self.assertEqual(RangeCheck.props.int64.minimum, minint64)
481 self.assertEqual(RangeCheck.props.int64.maximum, maxint64)
482 self.assertEqual(RangeCheck.props.uint64.minimum, 0)
483 self.assertEqual(RangeCheck.props.uint64.maximum, maxuint64)
486 for key, (gtype, min, max) in types_.items():
487 self.assertEqual(obj.get_property(key),
488 getattr(RangeCheck.props, key).default_value)
490 obj.set_property(key, min)
491 self.assertEqual(obj.get_property(key), min)
493 obj.set_property(key, max)
494 self.assertEqual(obj.get_property(key), max)
496 def test_multi(self):
497 obj = PropertyObject()
498 obj.set_properties(normal="foo",
500 normal, uint64 = obj.get_properties("normal", "uint64")
501 self.assertEqual(normal, "foo")
502 self.assertEqual(uint64, 7)
505 class TestProperty(unittest.TestCase):
506 def test_simple(self):
507 class C(GObject.GObject):
508 str = GObject.Property(type=str)
509 int = GObject.Property(type=int)
510 float = GObject.Property(type=float)
511 long = GObject.Property(type=_long)
513 self.assertTrue(hasattr(C.props, 'str'))
514 self.assertTrue(hasattr(C.props, 'int'))
515 self.assertTrue(hasattr(C.props, 'float'))
516 self.assertTrue(hasattr(C.props, 'long'))
519 self.assertEqual(o.str, '')
521 self.assertEqual(o.str, 'str')
523 self.assertEqual(o.int, 0)
525 self.assertEqual(o.int, 1138)
527 self.assertEqual(o.float, 0.0)
529 self.assertEqual(o.float, 3.14)
531 self.assertEqual(o.long, _long(0))
533 self.assertEqual(o.long, _long(100))
535 def test_custom_getter(self):
536 class C(GObject.GObject):
539 prop = GObject.Property(getter=get_prop)
542 self.assertEqual(o.prop, 'value')
543 self.assertRaises(TypeError, setattr, o, 'prop', 'xxx')
545 @unittest.expectedFailure # https://bugzilla.gnome.org/show_bug.cgi?id=575652
546 def test_getter_exception(self):
547 class C(GObject.Object):
548 @GObject.Property(type=int)
550 raise ValueError('something bad happend')
553 with self.assertRaisesRegex(ValueError, 'something bad happend'):
556 with self.assertRaisesRegex(ValueError, 'something bad happend'):
557 o.get_property('prop')
559 with self.assertRaisesRegex(ValueError, 'something bad happend'):
562 def test_custom_setter(self):
563 class C(GObject.GObject):
564 def set_prop(self, value):
566 prop = GObject.Property(setter=set_prop)
570 GObject.GObject.__init__(self)
573 self.assertEqual(o._value, None)
575 self.assertEqual(o._value, 'bar')
576 self.assertRaises(TypeError, getattr, o, 'prop')
578 def test_decorator_default(self):
579 class C(GObject.GObject):
587 def value_setter(self, value):
591 self.assertEqual(o.value, 'value')
593 self.assertEqual(o.value, 'blah')
594 self.assertEqual(o.props.value, 'blah')
596 def test_decorator_private_setter(self):
597 class C(GObject.GObject):
605 def _set_value(self, value):
609 self.assertEqual(o.value, 'value')
611 self.assertEqual(o.value, 'blah')
612 self.assertEqual(o.props.value, 'blah')
614 def test_decorator_with_call(self):
615 class C(GObject.GObject):
618 @GObject.Property(type=int, default=1, minimum=1, maximum=10)
619 def typedValue(self):
623 def typedValue_setter(self, value):
627 self.assertEqual(o.typedValue, 1)
629 self.assertEqual(o.typedValue, 5)
630 self.assertEqual(o.props.typedValue, 5)
632 def test_errors(self):
633 self.assertRaises(TypeError, GObject.Property, type='str')
634 self.assertRaises(TypeError, GObject.Property, nick=False)
635 self.assertRaises(TypeError, GObject.Property, blurb=False)
636 # this never fail while bool is a subclass of int
639 # self.assertRaises(TypeError, GObject.Property, type=bool, default=0)
640 self.assertRaises(TypeError, GObject.Property, type=bool, default='ciao mamma')
641 self.assertRaises(TypeError, GObject.Property, type=bool)
642 self.assertRaises(TypeError, GObject.Property, type=object, default=0)
643 self.assertRaises(TypeError, GObject.Property, type=complex)
645 def test_defaults(self):
646 GObject.Property(type=bool, default=True)
647 GObject.Property(type=bool, default=False)
649 def test_name_with_underscore(self):
650 class C(GObject.GObject):
651 prop_name = GObject.Property(type=int)
654 self.assertEqual(o.prop_name, 10)
656 def test_range(self):
658 (TYPE_INT, MININT, MAXINT),
659 (TYPE_UINT, 0, MAXUINT),
660 (TYPE_LONG, MINLONG, MAXLONG),
661 (TYPE_ULONG, 0, MAXULONG),
662 (TYPE_INT64, MININT64, MAXINT64),
663 (TYPE_UINT64, 0, MAXUINT64),
666 for gtype, min, max in types_:
667 # Normal, everything is alright
668 prop = GObject.Property(type=gtype, minimum=min, maximum=max)
669 subtype = type('', (GObject.GObject,), dict(prop=prop))
670 self.assertEqual(subtype.props.prop.minimum, min)
671 self.assertEqual(subtype.props.prop.maximum, max)
674 self.assertRaises(TypeError,
675 GObject.Property, type=gtype, minimum=min - 1,
678 # Higher than maximum
679 self.assertRaises(TypeError,
680 GObject.Property, type=gtype, minimum=min,
683 def test_min_max(self):
684 class C(GObject.GObject):
685 prop_int = GObject.Property(type=int, minimum=1, maximum=100, default=1)
686 prop_float = GObject.Property(type=float, minimum=0.1, maximum=10.5, default=1.1)
689 GObject.GObject.__init__(self)
691 # we test known-bad values here which cause Gtk-WARNING logs.
692 # Explicitly allow these for this test.
693 old_mask = GLib.log_set_always_fatal(GLib.LogLevelFlags.LEVEL_CRITICAL)
696 self.assertEqual(o.prop_int, 1)
699 self.assertEqual(o.prop_int, 5)
702 self.assertEqual(o.prop_int, 5)
705 self.assertEqual(o.prop_int, 5)
707 self.assertEqual(o.prop_float, 1.1)
710 self.assertEqual(o.prop_float, 7.75)
713 self.assertEqual(o.prop_float, 7.75)
716 self.assertEqual(o.prop_float, 7.75)
718 GLib.log_set_always_fatal(old_mask)
720 def test_multiple_instances(self):
721 class C(GObject.GObject):
722 prop = GObject.Property(type=str, default='default')
726 self.assertEqual(o1.prop, 'default')
727 self.assertEqual(o2.prop, 'default')
729 self.assertEqual(o1.prop, 'value')
730 self.assertEqual(o2.prop, 'default')
732 def test_object_property(self):
733 class PropertyObject(GObject.GObject):
734 obj = GObject.Property(type=GObject.GObject)
736 pobj1 = PropertyObject()
737 obj1_hash = hash(pobj1)
738 pobj2 = PropertyObject()
743 self.assertEqual(hash(pobj1), obj1_hash)
745 def test_object_subclass_property(self):
746 class ObjectSubclass(GObject.GObject):
747 __gtype_name__ = 'ObjectSubclass'
749 class PropertyObjectSubclass(GObject.GObject):
750 obj = GObject.Property(type=ObjectSubclass)
752 PropertyObjectSubclass(obj=ObjectSubclass())
754 def test_property_subclass(self):
756 class A(GObject.GObject):
757 prop1 = GObject.Property(type=int)
760 prop2 = GObject.Property(type=int)
764 self.assertEqual(b.prop2, 10)
766 self.assertEqual(b.prop1, 20)
768 @unittest.skipUnless(has_regress, 'Missing regress typelib')
769 def test_property_subclass_c(self):
770 class A(Regress.TestSubObj):
771 prop1 = GObject.Property(type=int)
775 self.assertEqual(a.prop1, 10)
777 # also has parent properties
779 self.assertEqual(a.props.int, 20)
781 # Some of which are unusable without introspection
782 a.props.list = ("str1", "str2")
783 self.assertEqual(a.props.list, ["str1", "str2"])
785 a.set_property("list", ("str3", "str4"))
786 self.assertEqual(a.props.list, ["str3", "str4"])
788 def test_property_subclass_custom_setter(self):
790 class A(GObject.GObject):
793 first = GObject.Property(type=str, getter=get_first)
796 def get_second(self):
798 second = GObject.Property(type=str, getter=get_second)
801 self.assertEqual(a.first, 'first')
802 self.assertRaises(TypeError, setattr, a, 'first', 'foo')
805 self.assertEqual(b.first, 'first')
806 self.assertRaises(TypeError, setattr, b, 'first', 'foo')
807 self.assertEqual(b.second, 'second')
808 self.assertRaises(TypeError, setattr, b, 'second', 'foo')
810 def test_property_subclass_custom_setter_error(self):
812 class A(GObject.GObject):
815 first = GObject.Property(type=str, getter=get_first)
817 def do_get_property(self, pspec):
826 def test_float_min(self):
827 GObject.Property(type=float, minimum=-1)
828 GObject.Property(type=GObject.TYPE_FLOAT, minimum=-1)
829 GObject.Property(type=GObject.TYPE_DOUBLE, minimum=-1)
833 def test_reference_count(self):
834 # We can check directly if an object gets finalized, so we will
835 # observe it indirectly through the refcount of a member object.
837 # We create our dummy object and store its current refcount
839 rc = sys.getrefcount(o)
841 # We add our object as a member to our newly created object we
842 # want to observe. Its refcount is increased by one.
843 t = PropertyObject(normal="test")
845 self.assertEqual(sys.getrefcount(o), rc + 1)
847 # Now we want to ensure we do not leak any references to our
848 # object with properties. If no ref is leaked, then when deleting
849 # the local reference to this object, its reference count shoud
850 # drop to zero, and our dummy object should loose one reference.
852 self.assertEqual(sys.getrefcount(o), rc)
854 def test_doc_strings(self):
855 class C(GObject.GObject):
856 foo_blurbed = GObject.Property(type=int, blurb='foo_blurbed doc string')
859 def foo_getter(self):
860 """foo_getter doc string"""
863 self.assertEqual(C.foo_blurbed.blurb, 'foo_blurbed doc string')
864 self.assertEqual(C.foo_blurbed.__doc__, 'foo_blurbed doc string')
866 self.assertEqual(C.foo_getter.blurb, 'foo_getter doc string')
867 self.assertEqual(C.foo_getter.__doc__, 'foo_getter doc string')
869 def test_python_to_glib_type_mapping(self):
870 tester = GObject.Property()
871 self.assertEqual(tester._type_from_python(int), GObject.TYPE_INT)
872 if sys.version_info < (3, 0):
873 self.assertEqual(tester._type_from_python(long), GObject.TYPE_LONG)
874 self.assertEqual(tester._type_from_python(bool), GObject.TYPE_BOOLEAN)
875 self.assertEqual(tester._type_from_python(float), GObject.TYPE_DOUBLE)
876 self.assertEqual(tester._type_from_python(str), GObject.TYPE_STRING)
877 self.assertEqual(tester._type_from_python(object), GObject.TYPE_PYOBJECT)
879 self.assertEqual(tester._type_from_python(GObject.GObject), GObject.GObject.__gtype__)
880 self.assertEqual(tester._type_from_python(GObject.GEnum), GObject.GEnum.__gtype__)
881 self.assertEqual(tester._type_from_python(GObject.GFlags), GObject.GFlags.__gtype__)
882 self.assertEqual(tester._type_from_python(GObject.GBoxed), GObject.GBoxed.__gtype__)
883 self.assertEqual(tester._type_from_python(GObject.GInterface), GObject.GInterface.__gtype__)
885 for type_ in [TYPE_NONE, TYPE_INTERFACE, TYPE_CHAR, TYPE_UCHAR,
886 TYPE_INT, TYPE_UINT, TYPE_BOOLEAN, TYPE_LONG,
887 TYPE_ULONG, TYPE_INT64, TYPE_UINT64,
888 TYPE_FLOAT, TYPE_DOUBLE, TYPE_POINTER,
889 TYPE_BOXED, TYPE_PARAM, TYPE_OBJECT, TYPE_STRING,
890 TYPE_PYOBJECT, TYPE_GTYPE, TYPE_STRV]:
891 self.assertEqual(tester._type_from_python(type_), type_)
893 self.assertRaises(TypeError, tester._type_from_python, types.CodeType)
896 class TestInstallProperties(unittest.TestCase):
897 # These tests only test how signalhelper.install_signals works
898 # with the __gsignals__ dict and therefore does not need to use
899 # GObject as a base class because that would automatically call
900 # install_signals within the meta-class.
902 __gproperties__ = {'test': (0, '', '', 0, 0, 0, 0)}
908 @GObject.Property(type=int)
912 class ClassWithPropertyAndGetterVFunc(object):
913 @GObject.Property(type=int)
917 def do_get_property(self, name):
920 class ClassWithPropertyRedefined(object):
921 __gproperties__ = {'test': (0, '', '', 0, 0, 0, 0)}
922 test = GObject.Property(type=int)
925 self.assertEqual(len(self.Base.__gproperties__), 1)
926 propertyhelper.install_properties(self.Base)
927 self.assertEqual(len(self.Base.__gproperties__), 1)
929 def test_subclass_without_properties_is_not_modified(self):
930 self.assertFalse('__gproperties__' in self.Sub1.__dict__)
931 propertyhelper.install_properties(self.Sub1)
932 self.assertFalse('__gproperties__' in self.Sub1.__dict__)
934 def test_subclass_with_decorator_gets_gproperties_dict(self):
935 # Sub2 has Property instances but will not have a __gproperties__
936 # until install_properties is called
937 self.assertFalse('__gproperties__' in self.Sub2.__dict__)
938 self.assertFalse('do_get_property' in self.Sub2.__dict__)
939 self.assertFalse('do_set_property' in self.Sub2.__dict__)
941 propertyhelper.install_properties(self.Sub2)
942 self.assertTrue('__gproperties__' in self.Sub2.__dict__)
943 self.assertEqual(len(self.Base.__gproperties__), 1)
944 self.assertEqual(len(self.Sub2.__gproperties__), 1)
945 self.assertTrue('sub2test' in self.Sub2.__gproperties__)
947 # get/set vfuncs should have been added
948 self.assertTrue('do_get_property' in self.Sub2.__dict__)
949 self.assertTrue('do_set_property' in self.Sub2.__dict__)
951 def test_object_with_property_and_do_get_property_vfunc_raises(self):
952 self.assertRaises(TypeError, propertyhelper.install_properties,
953 self.ClassWithPropertyAndGetterVFunc)
955 def test_same_name_property_definitions_raises(self):
956 self.assertRaises(ValueError, propertyhelper.install_properties,
957 self.ClassWithPropertyRedefined)
960 class CPropertiesTestBase(object):
961 # Tests for properties implemented in C not Python.
964 self.obj = GIMarshallingTests.PropertiesObject()
966 def get_prop(self, obj, name):
967 raise NotImplementedError
969 def set_prop(self, obj, name, value):
970 raise NotImplementedError
972 def test_boolean(self):
973 self.assertEqual(self.get_prop(self.obj, 'some-boolean'), False)
974 self.set_prop(self.obj, 'some-boolean', True)
975 self.assertEqual(self.get_prop(self.obj, 'some-boolean'), True)
977 obj = GIMarshallingTests.PropertiesObject(some_boolean=True)
978 self.assertEqual(self.get_prop(obj, 'some-boolean'), True)
981 self.assertEqual(self.get_prop(self.obj, 'some-char'), 0)
982 self.set_prop(self.obj, 'some-char', GLib.MAXINT8)
983 self.assertEqual(self.get_prop(self.obj, 'some-char'), GLib.MAXINT8)
985 obj = GIMarshallingTests.PropertiesObject(some_char=-42)
986 self.assertEqual(self.get_prop(obj, 'some-char'), -42)
988 def test_uchar(self):
989 self.assertEqual(self.get_prop(self.obj, 'some-uchar'), 0)
990 self.set_prop(self.obj, 'some-uchar', GLib.MAXUINT8)
991 self.assertEqual(self.get_prop(self.obj, 'some-uchar'), GLib.MAXUINT8)
993 obj = GIMarshallingTests.PropertiesObject(some_uchar=42)
994 self.assertEqual(self.get_prop(obj, 'some-uchar'), 42)
997 self.assertEqual(self.get_prop(self.obj, 'some_int'), 0)
998 self.set_prop(self.obj, 'some-int', GLib.MAXINT)
999 self.assertEqual(self.get_prop(self.obj, 'some_int'), GLib.MAXINT)
1001 obj = GIMarshallingTests.PropertiesObject(some_int=-42)
1002 self.assertEqual(self.get_prop(obj, 'some-int'), -42)
1004 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-int', 'foo')
1005 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-int', None)
1007 self.assertEqual(self.get_prop(obj, 'some-int'), -42)
1009 def test_uint(self):
1010 self.assertEqual(self.get_prop(self.obj, 'some_uint'), 0)
1011 self.set_prop(self.obj, 'some-uint', GLib.MAXUINT)
1012 self.assertEqual(self.get_prop(self.obj, 'some_uint'), GLib.MAXUINT)
1014 obj = GIMarshallingTests.PropertiesObject(some_uint=42)
1015 self.assertEqual(self.get_prop(obj, 'some-uint'), 42)
1017 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-uint', 'foo')
1018 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-uint', None)
1020 self.assertEqual(self.get_prop(obj, 'some-uint'), 42)
1022 def test_long(self):
1023 self.assertEqual(self.get_prop(self.obj, 'some_long'), 0)
1024 self.set_prop(self.obj, 'some-long', GLib.MAXLONG)
1025 self.assertEqual(self.get_prop(self.obj, 'some_long'), GLib.MAXLONG)
1027 obj = GIMarshallingTests.PropertiesObject(some_long=-42)
1028 self.assertEqual(self.get_prop(obj, 'some-long'), -42)
1030 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-long', 'foo')
1031 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-long', None)
1033 self.assertEqual(self.get_prop(obj, 'some-long'), -42)
1035 def test_ulong(self):
1036 self.assertEqual(self.get_prop(self.obj, 'some_ulong'), 0)
1037 self.set_prop(self.obj, 'some-ulong', GLib.MAXULONG)
1038 self.assertEqual(self.get_prop(self.obj, 'some_ulong'), GLib.MAXULONG)
1040 obj = GIMarshallingTests.PropertiesObject(some_ulong=42)
1041 self.assertEqual(self.get_prop(obj, 'some-ulong'), 42)
1043 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-ulong', 'foo')
1044 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-ulong', None)
1046 self.assertEqual(self.get_prop(obj, 'some-ulong'), 42)
1048 def test_int64(self):
1049 self.assertEqual(self.get_prop(self.obj, 'some-int64'), 0)
1050 self.set_prop(self.obj, 'some-int64', GLib.MAXINT64)
1051 self.assertEqual(self.get_prop(self.obj, 'some-int64'), GLib.MAXINT64)
1053 obj = GIMarshallingTests.PropertiesObject(some_int64=-4200000000000000)
1054 self.assertEqual(self.get_prop(obj, 'some-int64'), -4200000000000000)
1056 def test_uint64(self):
1057 self.assertEqual(self.get_prop(self.obj, 'some-uint64'), 0)
1058 self.set_prop(self.obj, 'some-uint64', GLib.MAXUINT64)
1059 self.assertEqual(self.get_prop(self.obj, 'some-uint64'), GLib.MAXUINT64)
1061 obj = GIMarshallingTests.PropertiesObject(some_uint64=4200000000000000)
1062 self.assertEqual(self.get_prop(obj, 'some-uint64'), 4200000000000000)
1064 def test_float(self):
1065 self.assertEqual(self.get_prop(self.obj, 'some-float'), 0)
1066 self.set_prop(self.obj, 'some-float', GLib.MAXFLOAT)
1067 self.assertEqual(self.get_prop(self.obj, 'some-float'), GLib.MAXFLOAT)
1069 obj = GIMarshallingTests.PropertiesObject(some_float=42.42)
1070 self.assertAlmostEqual(self.get_prop(obj, 'some-float'), 42.42, 4)
1072 obj = GIMarshallingTests.PropertiesObject(some_float=42)
1073 self.assertAlmostEqual(self.get_prop(obj, 'some-float'), 42.0, 4)
1075 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-float', 'foo')
1076 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-float', None)
1078 self.assertAlmostEqual(self.get_prop(obj, 'some-float'), 42.0, 4)
1080 def test_double(self):
1081 self.assertEqual(self.get_prop(self.obj, 'some-double'), 0)
1082 self.set_prop(self.obj, 'some-double', GLib.MAXDOUBLE)
1083 self.assertEqual(self.get_prop(self.obj, 'some-double'), GLib.MAXDOUBLE)
1085 obj = GIMarshallingTests.PropertiesObject(some_double=42.42)
1086 self.assertAlmostEqual(self.get_prop(obj, 'some-double'), 42.42)
1088 obj = GIMarshallingTests.PropertiesObject(some_double=42)
1089 self.assertAlmostEqual(self.get_prop(obj, 'some-double'), 42.0)
1091 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-double', 'foo')
1092 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-double', None)
1094 self.assertAlmostEqual(self.get_prop(obj, 'some-double'), 42.0)
1096 def test_strv(self):
1097 self.assertEqual(self.get_prop(self.obj, 'some-strv'), [])
1098 self.set_prop(self.obj, 'some-strv', ['hello', 'world'])
1099 self.assertEqual(self.get_prop(self.obj, 'some-strv'), ['hello', 'world'])
1101 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-strv', 1)
1102 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-strv', 'foo')
1103 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-strv', [1, 2])
1104 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-strv', ['foo', 1])
1106 self.assertEqual(self.get_prop(self.obj, 'some-strv'), ['hello', 'world'])
1108 obj = GIMarshallingTests.PropertiesObject(some_strv=['hello', 'world'])
1109 self.assertEqual(self.get_prop(obj, 'some-strv'), ['hello', 'world'])
1111 def test_boxed_struct(self):
1112 self.assertEqual(self.get_prop(self.obj, 'some-boxed-struct'), None)
1115 __gtype__ = GObject.TYPE_STRV
1117 struct1 = GIMarshallingTests.BoxedStruct()
1120 self.set_prop(self.obj, 'some-boxed-struct', struct1)
1121 self.assertEqual(self.get_prop(self.obj, 'some-boxed-struct').long_, 1)
1122 self.assertEqual(self.obj.some_boxed_struct.long_, 1)
1124 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-boxed-struct', 1)
1125 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-boxed-struct', 'foo')
1127 obj = GIMarshallingTests.PropertiesObject(some_boxed_struct=struct1)
1128 self.assertEqual(self.get_prop(obj, 'some-boxed-struct').long_, 1)
1130 def test_boxed_glist(self):
1131 self.assertEqual(self.get_prop(self.obj, 'some-boxed-glist'), [])
1133 l = [GLib.MININT, 42, GLib.MAXINT]
1134 self.set_prop(self.obj, 'some-boxed-glist', l)
1135 self.assertEqual(self.get_prop(self.obj, 'some-boxed-glist'), l)
1136 self.set_prop(self.obj, 'some-boxed-glist', [])
1137 self.assertEqual(self.get_prop(self.obj, 'some-boxed-glist'), [])
1139 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-boxed-glist', 1)
1140 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-boxed-glist', 'foo')
1141 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-boxed-glist', ['a'])
1143 @unittest.skipUnless(has_regress, 'built without cairo support')
1144 def test_annotated_glist(self):
1145 obj = Regress.TestObj()
1146 self.assertEqual(self.get_prop(obj, 'list'), [])
1148 self.set_prop(obj, 'list', ['1', '2', '3'])
1149 self.assertTrue(isinstance(self.get_prop(obj, 'list'), list))
1150 self.assertEqual(self.get_prop(obj, 'list'), ['1', '2', '3'])
1152 @unittest.expectedFailure
1153 def test_boxed_glist_ctor(self):
1154 l = [GLib.MININT, 42, GLib.MAXINT]
1155 obj = GIMarshallingTests.PropertiesObject(some_boxed_glist=l)
1156 self.assertEqual(self.get_prop(obj, 'some-boxed-glist'), l)
1158 def test_variant(self):
1159 self.assertEqual(self.get_prop(self.obj, 'some-variant'), None)
1161 self.set_prop(self.obj, 'some-variant', GLib.Variant('o', '/myobj'))
1162 self.assertEqual(self.get_prop(self.obj, 'some-variant').get_type_string(), 'o')
1163 self.assertEqual(self.get_prop(self.obj, 'some-variant').print_(False), "'/myobj'")
1165 self.set_prop(self.obj, 'some-variant', None)
1166 self.assertEqual(self.get_prop(self.obj, 'some-variant'), None)
1168 obj = GIMarshallingTests.PropertiesObject(some_variant=GLib.Variant('b', True))
1169 self.assertEqual(self.get_prop(obj, 'some-variant').get_type_string(), 'b')
1170 self.assertEqual(self.get_prop(obj, 'some-variant').get_boolean(), True)
1172 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-variant', 'foo')
1173 self.assertRaises(TypeError, self.set_prop, self.obj, 'some-variant', 23)
1175 self.assertEqual(self.get_prop(obj, 'some-variant').get_type_string(), 'b')
1176 self.assertEqual(self.get_prop(obj, 'some-variant').get_boolean(), True)
1178 def test_setting_several_properties(self):
1179 obj = GIMarshallingTests.PropertiesObject()
1180 obj.set_properties(some_uchar=54, some_int=42)
1181 self.assertEqual(42, self.get_prop(obj, 'some-int'))
1182 self.assertEqual(54, self.get_prop(obj, 'some-uchar'))
1184 @unittest.skipUnless(has_regress, 'built without cairo support')
1185 def test_gtype(self):
1186 obj = Regress.TestObj()
1187 self.assertEqual(self.get_prop(obj, 'gtype'), GObject.TYPE_INVALID)
1188 self.set_prop(obj, 'gtype', int)
1189 self.assertEqual(self.get_prop(obj, 'gtype'), GObject.TYPE_INT)
1191 obj = Regress.TestObj(gtype=int)
1192 self.assertEqual(self.get_prop(obj, 'gtype'), GObject.TYPE_INT)
1193 self.set_prop(obj, 'gtype', str)
1194 self.assertEqual(self.get_prop(obj, 'gtype'), GObject.TYPE_STRING)
1196 @unittest.skipUnless(has_regress, 'built without cairo support')
1197 def test_hash_table(self):
1198 obj = Regress.TestObj()
1199 self.assertEqual(self.get_prop(obj, 'hash-table'), None)
1201 self.set_prop(obj, 'hash-table', {'mec': 56})
1202 self.assertTrue(isinstance(self.get_prop(obj, 'hash-table'), dict))
1203 self.assertEqual(list(self.get_prop(obj, 'hash-table').items())[0],
1206 @unittest.skipUnless(has_regress, 'built without cairo support')
1207 def test_parent_class(self):
1208 class A(Regress.TestObj):
1209 prop1 = GObject.Property(type=int)
1212 self.set_prop(a, 'int', 20)
1213 self.assertEqual(self.get_prop(a, 'int'), 20)
1215 # test parent property which needs introspection
1216 self.set_prop(a, 'list', ("str1", "str2"))
1217 self.assertEqual(self.get_prop(a, 'list'), ["str1", "str2"])
1219 def test_held_object_ref_count_getter(self):
1220 holder = GIMarshallingTests.PropertiesObject()
1221 held = GObject.Object()
1223 self.assertEqual(holder.__grefcount__, 1)
1224 self.assertEqual(held.__grefcount__, 1)
1226 self.set_prop(holder, 'some-object', held)
1227 self.assertEqual(holder.__grefcount__, 1)
1229 initial_ref_count = held.__grefcount__
1230 self.get_prop(holder, 'some-object')
1232 self.assertEqual(held.__grefcount__, initial_ref_count)
1234 def test_held_object_ref_count_setter(self):
1235 holder = GIMarshallingTests.PropertiesObject()
1236 held = GObject.Object()
1238 self.assertEqual(holder.__grefcount__, 1)
1239 self.assertEqual(held.__grefcount__, 1)
1241 # Setting property should only increase ref count by 1
1242 self.set_prop(holder, 'some-object', held)
1243 self.assertEqual(holder.__grefcount__, 1)
1244 self.assertEqual(held.__grefcount__, 2)
1246 # Clearing should pull it back down
1247 self.set_prop(holder, 'some-object', None)
1248 self.assertEqual(held.__grefcount__, 1)
1250 def test_set_object_property_to_invalid_type(self):
1251 obj = GIMarshallingTests.PropertiesObject()
1252 self.assertRaises(TypeError, self.set_prop, obj, 'some-object', 'not_an_object')
1255 class TestCPropsAccessor(CPropertiesTestBase, unittest.TestCase):
1256 # C property tests using the "props" accessor.
1257 def get_prop(self, obj, name):
1258 return getattr(obj.props, name.replace('-', '_'))
1260 def set_prop(self, obj, name, value):
1261 setattr(obj.props, name.replace('-', '_'), value)
1263 def test_props_accessor_dir(self):
1265 props = dir(GIMarshallingTests.PropertiesObject.props)
1266 self.assertTrue('some_float' in props)
1267 self.assertTrue('some_double' in props)
1268 self.assertTrue('some_variant' in props)
1271 obj = GIMarshallingTests.PropertiesObject()
1272 props = dir(obj.props)
1273 self.assertTrue('some_float' in props)
1274 self.assertTrue('some_double' in props)
1275 self.assertTrue('some_variant' in props)
1277 def test_param_spec_dir(self):
1278 attrs = dir(GIMarshallingTests.PropertiesObject.props.some_float)
1279 self.assertTrue('name' in attrs)
1280 self.assertTrue('nick' in attrs)
1281 self.assertTrue('blurb' in attrs)
1282 self.assertTrue('flags' in attrs)
1283 self.assertTrue('default_value' in attrs)
1284 self.assertTrue('minimum' in attrs)
1285 self.assertTrue('maximum' in attrs)
1288 class TestCGetPropertyMethod(CPropertiesTestBase, unittest.TestCase):
1289 # C property tests using the "props" accessor.
1290 def get_prop(self, obj, name):
1291 return obj.get_property(name)
1293 def set_prop(self, obj, name, value):
1294 obj.set_property(name, value)
1297 if __name__ == '__main__':