Some error handling/reporting fixes.
[pygobject.git] / tests / test_gobject.py
blob87b0e4ca34187d5396c06fd54ea568bdad2bb216
1 # -*- Mode: Python -*-
3 import sys
4 import gc
5 import unittest
6 import warnings
8 from gi.repository import GObject, GLib
9 from gi import PyGIDeprecationWarning
10 from gi.module import get_introspection_module
12 import gi
13 _gobject = gi._gi._gobject
15 import testhelper
18 class TestGObjectAPI(unittest.TestCase):
19 def test_gobject_inheritance(self):
20 # GObject.Object is a class hierarchy as follows:
21 # overrides.Object -> introspection.Object -> static.GObject
22 GIObjectModule = get_introspection_module('GObject')
23 self.assertTrue(issubclass(GObject.Object, GIObjectModule.Object))
24 self.assertTrue(issubclass(GIObjectModule.Object, _gobject.GObject))
26 self.assertEqual(_gobject.GObject.__gtype__, GObject.TYPE_OBJECT)
27 self.assertEqual(GIObjectModule.Object.__gtype__, GObject.TYPE_OBJECT)
28 self.assertEqual(GObject.Object.__gtype__, GObject.TYPE_OBJECT)
30 # The pytype wrapper should hold the outer most Object class from overrides.
31 self.assertEqual(GObject.TYPE_OBJECT.pytype, GObject.Object)
33 def test_gobject_unsupported_overrides(self):
34 obj = GObject.Object()
36 with self.assertRaisesRegex(RuntimeError, 'Data access methods are unsupported.*'):
37 obj.get_data()
39 with self.assertRaisesRegex(RuntimeError, 'This method is currently unsupported.*'):
40 obj.force_floating()
42 def test_compat_api(self):
43 with warnings.catch_warnings(record=True) as w:
44 warnings.simplefilter('always')
45 # GObject formerly exposed a lot of GLib's functions
46 self.assertEqual(GObject.markup_escape_text('foo'), 'foo')
48 ml = GObject.MainLoop()
49 self.assertFalse(ml.is_running())
51 context = GObject.main_context_default()
52 self.assertTrue(context.pending() in [False, True])
54 context = GObject.MainContext()
55 self.assertFalse(context.pending())
57 self.assertTrue(issubclass(w[0].category, PyGIDeprecationWarning))
58 self.assertTrue('GLib.markup_escape_text' in str(w[0]), str(w[0]))
60 self.assertLess(GObject.PRIORITY_HIGH, GObject.PRIORITY_DEFAULT)
62 def test_min_max_int(self):
63 with warnings.catch_warnings():
64 warnings.simplefilter('ignore', PyGIDeprecationWarning)
66 self.assertEqual(GObject.G_MAXINT16, 2 ** 15 - 1)
67 self.assertEqual(GObject.G_MININT16, -2 ** 15)
68 self.assertEqual(GObject.G_MAXUINT16, 2 ** 16 - 1)
70 self.assertEqual(GObject.G_MAXINT32, 2 ** 31 - 1)
71 self.assertEqual(GObject.G_MININT32, -2 ** 31)
72 self.assertEqual(GObject.G_MAXUINT32, 2 ** 32 - 1)
74 self.assertEqual(GObject.G_MAXINT64, 2 ** 63 - 1)
75 self.assertEqual(GObject.G_MININT64, -2 ** 63)
76 self.assertEqual(GObject.G_MAXUINT64, 2 ** 64 - 1)
79 class TestReferenceCounting(unittest.TestCase):
80 def test_regular_object(self):
81 obj = GObject.GObject()
82 self.assertEqual(obj.__grefcount__, 1)
84 obj = GObject.new(GObject.GObject)
85 self.assertEqual(obj.__grefcount__, 1)
87 def test_floating(self):
88 obj = testhelper.Floating()
89 self.assertEqual(obj.__grefcount__, 1)
91 obj = GObject.new(testhelper.Floating)
92 self.assertEqual(obj.__grefcount__, 1)
94 def test_owned_by_library(self):
95 # Upon creation, the refcount of the object should be 2:
96 # - someone already has a reference on the new object.
97 # - the python wrapper should hold its own reference.
98 obj = testhelper.OwnedByLibrary()
99 self.assertEqual(obj.__grefcount__, 2)
101 # We ask the library to release its reference, so the only
102 # remaining ref should be our wrapper's. Once the wrapper
103 # will run out of scope, the object will get finalized.
104 obj.release()
105 self.assertEqual(obj.__grefcount__, 1)
107 def test_owned_by_library_out_of_scope(self):
108 obj = testhelper.OwnedByLibrary()
109 self.assertEqual(obj.__grefcount__, 2)
111 # We are manually taking the object out of scope. This means
112 # that our wrapper has been freed, and its reference dropped. We
113 # cannot check it but the refcount should now be 1 (the ref held
114 # by the library is still there, we didn't call release()
115 obj = None
117 # When we get the object back from the lib, the wrapper is
118 # re-created, so our refcount will be 2 once again.
119 obj = testhelper.owned_by_library_get_instance_list()[0]
120 self.assertEqual(obj.__grefcount__, 2)
122 obj.release()
123 self.assertEqual(obj.__grefcount__, 1)
125 def test_owned_by_library_using_gobject_new(self):
126 # Upon creation, the refcount of the object should be 2:
127 # - someone already has a reference on the new object.
128 # - the python wrapper should hold its own reference.
129 obj = GObject.new(testhelper.OwnedByLibrary)
130 self.assertEqual(obj.__grefcount__, 2)
132 # We ask the library to release its reference, so the only
133 # remaining ref should be our wrapper's. Once the wrapper
134 # will run out of scope, the object will get finalized.
135 obj.release()
136 self.assertEqual(obj.__grefcount__, 1)
138 def test_owned_by_library_out_of_scope_using_gobject_new(self):
139 obj = GObject.new(testhelper.OwnedByLibrary)
140 self.assertEqual(obj.__grefcount__, 2)
142 # We are manually taking the object out of scope. This means
143 # that our wrapper has been freed, and its reference dropped. We
144 # cannot check it but the refcount should now be 1 (the ref held
145 # by the library is still there, we didn't call release()
146 obj = None
148 # When we get the object back from the lib, the wrapper is
149 # re-created, so our refcount will be 2 once again.
150 obj = testhelper.owned_by_library_get_instance_list()[0]
151 self.assertEqual(obj.__grefcount__, 2)
153 obj.release()
154 self.assertEqual(obj.__grefcount__, 1)
156 def test_floating_and_sunk(self):
157 # Upon creation, the refcount of the object should be 2:
158 # - someone already has a reference on the new object.
159 # - the python wrapper should hold its own reference.
160 obj = testhelper.FloatingAndSunk()
161 self.assertEqual(obj.__grefcount__, 2)
163 # We ask the library to release its reference, so the only
164 # remaining ref should be our wrapper's. Once the wrapper
165 # will run out of scope, the object will get finalized.
166 obj.release()
167 self.assertEqual(obj.__grefcount__, 1)
169 def test_floating_and_sunk_out_of_scope(self):
170 obj = testhelper.FloatingAndSunk()
171 self.assertEqual(obj.__grefcount__, 2)
173 # We are manually taking the object out of scope. This means
174 # that our wrapper has been freed, and its reference dropped. We
175 # cannot check it but the refcount should now be 1 (the ref held
176 # by the library is still there, we didn't call release()
177 obj = None
179 # When we get the object back from the lib, the wrapper is
180 # re-created, so our refcount will be 2 once again.
181 obj = testhelper.floating_and_sunk_get_instance_list()[0]
182 self.assertEqual(obj.__grefcount__, 2)
184 obj.release()
185 self.assertEqual(obj.__grefcount__, 1)
187 def test_floating_and_sunk_using_gobject_new(self):
188 # Upon creation, the refcount of the object should be 2:
189 # - someone already has a reference on the new object.
190 # - the python wrapper should hold its own reference.
191 obj = GObject.new(testhelper.FloatingAndSunk)
192 self.assertEqual(obj.__grefcount__, 2)
194 # We ask the library to release its reference, so the only
195 # remaining ref should be our wrapper's. Once the wrapper
196 # will run out of scope, the object will get finalized.
197 obj.release()
198 self.assertEqual(obj.__grefcount__, 1)
200 def test_floating_and_sunk_out_of_scope_using_gobject_new(self):
201 obj = GObject.new(testhelper.FloatingAndSunk)
202 self.assertEqual(obj.__grefcount__, 2)
204 # We are manually taking the object out of scope. This means
205 # that our wrapper has been freed, and its reference dropped. We
206 # cannot check it but the refcount should now be 1 (the ref held
207 # by the library is still there, we didn't call release()
208 obj = None
210 # When we get the object back from the lib, the wrapper is
211 # re-created, so our refcount will be 2 once again.
212 obj = testhelper.floating_and_sunk_get_instance_list()[0]
213 self.assertEqual(obj.__grefcount__, 2)
215 obj.release()
216 self.assertEqual(obj.__grefcount__, 1)
218 def test_uninitialized_object(self):
219 class Obj(GObject.GObject):
220 def __init__(self):
221 x = self.__grefcount__
222 super(Obj, self).__init__()
223 assert x >= 0 # quiesce pyflakes
225 # Accessing __grefcount__ before the object is initialized is wrong.
226 # Ensure we get a proper exception instead of a crash.
227 self.assertRaises(TypeError, Obj)
230 class A(GObject.GObject):
231 def __init__(self):
232 super(A, self).__init__()
235 class TestPythonReferenceCounting(unittest.TestCase):
236 # Newly created instances should alwayshave two references: one for
237 # the GC, and one for the bound variable in the local scope.
239 def test_new_instance_has_two_refs(self):
240 obj = GObject.GObject()
241 self.assertEqual(sys.getrefcount(obj), 2)
243 def test_new_instance_has_two_refs_using_gobject_new(self):
244 obj = GObject.new(GObject.GObject)
245 self.assertEqual(sys.getrefcount(obj), 2)
247 def test_new_subclass_instance_has_two_refs(self):
248 obj = A()
249 self.assertEqual(sys.getrefcount(obj), 2)
251 def test_new_subclass_instance_has_two_refs_using_gobject_new(self):
252 obj = GObject.new(A)
253 self.assertEqual(sys.getrefcount(obj), 2)
256 class TestContextManagers(unittest.TestCase):
257 class ContextTestObject(GObject.GObject):
258 prop = GObject.Property(default=0, type=int)
260 def on_prop_set(self, obj, prop):
261 # Handler which tracks property changed notifications.
262 self.tracking.append(obj.get_property(prop.name))
264 def setUp(self):
265 self.tracking = []
266 self.obj = self.ContextTestObject()
267 self.handler = self.obj.connect('notify::prop', self.on_prop_set)
269 def test_freeze_notify_context(self):
270 # Verify prop tracking list
271 self.assertEqual(self.tracking, [])
272 self.obj.props.prop = 1
273 self.assertEqual(self.tracking, [1])
274 self.obj.props.prop = 2
275 self.assertEqual(self.tracking, [1, 2])
276 self.assertEqual(self.obj.__grefcount__, 1)
278 pyref_count = sys.getrefcount(self.obj)
280 # Using the context manager the tracking list should not be affected.
281 # The GObject reference count should stay the same and the python
282 # object ref-count should go up.
283 with self.obj.freeze_notify():
284 self.assertEqual(self.obj.__grefcount__, 1)
285 self.assertEqual(sys.getrefcount(self.obj), pyref_count + 1)
286 self.obj.props.prop = 3
287 self.assertEqual(self.obj.props.prop, 3)
288 self.assertEqual(self.tracking, [1, 2])
290 # After the context manager, the prop should have been modified,
291 # the tracking list will be modified, and the python object ref
292 # count goes back down.
293 gc.collect()
294 self.assertEqual(self.obj.props.prop, 3)
295 self.assertEqual(self.tracking, [1, 2, 3])
296 self.assertEqual(self.obj.__grefcount__, 1)
297 self.assertEqual(sys.getrefcount(self.obj), pyref_count)
299 def test_handler_block_context(self):
300 # Verify prop tracking list
301 self.assertEqual(self.tracking, [])
302 self.obj.props.prop = 1
303 self.assertEqual(self.tracking, [1])
304 self.obj.props.prop = 2
305 self.assertEqual(self.tracking, [1, 2])
306 self.assertEqual(self.obj.__grefcount__, 1)
308 pyref_count = sys.getrefcount(self.obj)
310 # Using the context manager the tracking list should not be affected.
311 # The GObject reference count should stay the same and the python
312 # object ref-count should go up.
313 with self.obj.handler_block(self.handler):
314 self.assertEqual(self.obj.__grefcount__, 1)
315 self.assertEqual(sys.getrefcount(self.obj), pyref_count + 1)
316 self.obj.props.prop = 3
317 self.assertEqual(self.obj.props.prop, 3)
318 self.assertEqual(self.tracking, [1, 2])
320 # After the context manager, the prop should have been modified
321 # the tracking list should have stayed the same and the GObject ref
322 # count goes back down.
323 gc.collect()
324 self.assertEqual(self.obj.props.prop, 3)
325 self.assertEqual(self.tracking, [1, 2])
326 self.assertEqual(self.obj.__grefcount__, 1)
327 self.assertEqual(sys.getrefcount(self.obj), pyref_count)
329 def test_freeze_notify_context_nested(self):
330 self.assertEqual(self.tracking, [])
331 with self.obj.freeze_notify():
332 self.obj.props.prop = 1
333 self.assertEqual(self.tracking, [])
335 with self.obj.freeze_notify():
336 self.obj.props.prop = 2
337 self.assertEqual(self.tracking, [])
339 with self.obj.freeze_notify():
340 self.obj.props.prop = 3
341 self.assertEqual(self.tracking, [])
342 self.assertEqual(self.tracking, [])
343 self.assertEqual(self.tracking, [])
345 # Finally after last context, the notifications should have collapsed
346 # and the last one sent.
347 self.assertEqual(self.tracking, [3])
349 def test_handler_block_context_nested(self):
350 self.assertEqual(self.tracking, [])
351 with self.obj.handler_block(self.handler):
352 self.obj.props.prop = 1
353 self.assertEqual(self.tracking, [])
355 with self.obj.handler_block(self.handler):
356 self.obj.props.prop = 2
357 self.assertEqual(self.tracking, [])
359 with self.obj.handler_block(self.handler):
360 self.obj.props.prop = 3
361 self.assertEqual(self.tracking, [])
362 self.assertEqual(self.tracking, [])
363 self.assertEqual(self.tracking, [])
365 # Finally after last context, the notifications should have collapsed
366 # and the last one sent.
367 self.assertEqual(self.obj.props.prop, 3)
368 self.assertEqual(self.tracking, [])
370 def test_freeze_notify_normal_usage_ref_counts(self):
371 # Ensure ref counts without using methods as context managers
372 # maintain the same count.
373 self.assertEqual(self.obj.__grefcount__, 1)
374 self.obj.freeze_notify()
375 self.assertEqual(self.obj.__grefcount__, 1)
376 self.obj.thaw_notify()
377 self.assertEqual(self.obj.__grefcount__, 1)
379 def test_handler_block_normal_usage_ref_counts(self):
380 self.assertEqual(self.obj.__grefcount__, 1)
381 self.obj.handler_block(self.handler)
382 self.assertEqual(self.obj.__grefcount__, 1)
383 self.obj.handler_unblock(self.handler)
384 self.assertEqual(self.obj.__grefcount__, 1)
386 def test_freeze_notify_context_error(self):
387 # Test an exception occurring within a freeze context exits the context
388 try:
389 with self.obj.freeze_notify():
390 self.obj.props.prop = 1
391 self.assertEqual(self.tracking, [])
392 raise ValueError('Simulation')
393 except ValueError:
394 pass
396 # Verify the property set within the context called notify.
397 self.assertEqual(self.obj.props.prop, 1)
398 self.assertEqual(self.tracking, [1])
400 # Verify we are still not in a frozen context.
401 self.obj.props.prop = 2
402 self.assertEqual(self.tracking, [1, 2])
404 def test_handler_block_context_error(self):
405 # Test an exception occurring within a handler block exits the context
406 try:
407 with self.obj.handler_block(self.handler):
408 self.obj.props.prop = 1
409 self.assertEqual(self.tracking, [])
410 raise ValueError('Simulation')
411 except ValueError:
412 pass
414 # Verify the property set within the context didn't call notify.
415 self.assertEqual(self.obj.props.prop, 1)
416 self.assertEqual(self.tracking, [])
418 # Verify we are still not in a handler block context.
419 self.obj.props.prop = 2
420 self.assertEqual(self.tracking, [2])
423 @unittest.skipUnless(hasattr(GObject.Binding, 'unbind'),
424 'Requires newer GLib which has g_binding_unbind')
425 class TestPropertyBindings(unittest.TestCase):
426 class TestObject(GObject.GObject):
427 int_prop = GObject.Property(default=0, type=int)
429 def setUp(self):
430 self.source = self.TestObject()
431 self.target = self.TestObject()
433 def test_default_binding(self):
434 binding = self.source.bind_property('int_prop', self.target, 'int_prop',
435 GObject.BindingFlags.DEFAULT)
436 binding = binding # PyFlakes
438 # Test setting value on source gets pushed to target
439 self.source.int_prop = 1
440 self.assertEqual(self.source.int_prop, 1)
441 self.assertEqual(self.target.int_prop, 1)
443 # Test setting value on target does not change source
444 self.target.props.int_prop = 2
445 self.assertEqual(self.source.int_prop, 1)
446 self.assertEqual(self.target.int_prop, 2)
448 def test_bidirectional_binding(self):
449 binding = self.source.bind_property('int_prop', self.target, 'int_prop',
450 GObject.BindingFlags.BIDIRECTIONAL)
451 binding = binding # PyFlakes
453 # Test setting value on source gets pushed to target
454 self.source.int_prop = 1
455 self.assertEqual(self.source.int_prop, 1)
456 self.assertEqual(self.target.int_prop, 1)
458 # Test setting value on target also changes source
459 self.target.props.int_prop = 2
460 self.assertEqual(self.source.int_prop, 2)
461 self.assertEqual(self.target.int_prop, 2)
463 def test_transform_to_only(self):
464 def transform_to(binding, value, user_data=None):
465 self.assertEqual(user_data, 'test-data')
466 return value * 2
468 binding = self.source.bind_property('int_prop', self.target, 'int_prop',
469 GObject.BindingFlags.DEFAULT,
470 transform_to, None, 'test-data')
471 binding = binding # PyFlakes
473 self.source.int_prop = 1
474 self.assertEqual(self.source.int_prop, 1)
475 self.assertEqual(self.target.int_prop, 2)
477 self.target.props.int_prop = 1
478 self.assertEqual(self.source.int_prop, 1)
479 self.assertEqual(self.target.int_prop, 1)
481 def test_transform_from_only(self):
482 def transform_from(binding, value, user_data=None):
483 self.assertEqual(user_data, None)
484 return value * 2
486 binding = self.source.bind_property('int_prop', self.target, 'int_prop',
487 GObject.BindingFlags.BIDIRECTIONAL,
488 None, transform_from)
489 binding = binding # PyFlakes
491 self.source.int_prop = 1
492 self.assertEqual(self.source.int_prop, 1)
493 self.assertEqual(self.target.int_prop, 1)
495 self.target.props.int_prop = 1
496 self.assertEqual(self.source.int_prop, 2)
497 self.assertEqual(self.target.int_prop, 1)
499 def test_transform_bidirectional(self):
500 test_data = object()
502 def transform_to(binding, value, user_data=None):
503 self.assertEqual(user_data, test_data)
504 return value * 2
506 def transform_from(binding, value, user_data=None):
507 self.assertEqual(user_data, test_data)
508 return value // 2
510 test_data_ref_count = sys.getrefcount(test_data)
511 transform_to_ref_count = sys.getrefcount(transform_to)
512 transform_from_ref_count = sys.getrefcount(transform_from)
514 # bidirectional bindings
515 binding = self.source.bind_property('int_prop', self.target, 'int_prop',
516 GObject.BindingFlags.BIDIRECTIONAL,
517 transform_to, transform_from, test_data)
518 binding = binding # PyFlakes
519 binding_ref_count = sys.getrefcount(binding)
520 binding_gref_count = binding.__grefcount__
522 self.source.int_prop = 1
523 self.assertEqual(self.source.int_prop, 1)
524 self.assertEqual(self.target.int_prop, 2)
526 self.target.props.int_prop = 4
527 self.assertEqual(self.source.int_prop, 2)
528 self.assertEqual(self.target.int_prop, 4)
530 self.assertEqual(sys.getrefcount(binding), binding_ref_count)
531 self.assertEqual(binding.__grefcount__, binding_gref_count)
533 # test_data ref count increases by 2, once for each callback.
534 self.assertEqual(sys.getrefcount(test_data), test_data_ref_count + 2)
535 self.assertEqual(sys.getrefcount(transform_to), transform_to_ref_count + 1)
536 self.assertEqual(sys.getrefcount(transform_from), transform_from_ref_count + 1)
538 # Unbind should clear out the binding and its transforms
539 binding.unbind()
541 # Setting source or target should not change the other.
542 self.target.int_prop = 3
543 self.source.int_prop = 5
544 self.assertEqual(self.target.int_prop, 3)
545 self.assertEqual(self.source.int_prop, 5)
547 self.assertEqual(sys.getrefcount(test_data), test_data_ref_count)
548 self.assertEqual(sys.getrefcount(transform_to), transform_to_ref_count)
549 self.assertEqual(sys.getrefcount(transform_from), transform_from_ref_count)
551 def test_explicit_unbind_clears_connection(self):
552 self.assertEqual(self.source.int_prop, 0)
553 self.assertEqual(self.target.int_prop, 0)
555 # Test deleting binding reference removes binding.
556 binding = self.source.bind_property('int_prop', self.target, 'int_prop')
557 self.source.int_prop = 1
558 self.assertEqual(self.source.int_prop, 1)
559 self.assertEqual(self.target.int_prop, 1)
561 # unbind should clear out the bindings self reference
562 binding.unbind()
563 self.assertEqual(binding.__grefcount__, 1)
565 self.source.int_prop = 10
566 self.assertEqual(self.source.int_prop, 10)
567 self.assertEqual(self.target.int_prop, 1)
569 # An already unbound BindingWeakRef will raise if unbind is attempted a second time.
570 self.assertRaises(ValueError, binding.unbind)
572 def test_reference_counts(self):
573 self.assertEqual(self.source.__grefcount__, 1)
574 self.assertEqual(self.target.__grefcount__, 1)
576 # Binding ref count will be 2 do to the initial ref implicitly held by
577 # the act of binding and the ref incurred by using __call__ to generate
578 # a wrapper from the weak binding ref within python.
579 binding = self.source.bind_property('int_prop', self.target, 'int_prop')
580 self.assertEqual(binding.__grefcount__, 2)
582 # Creating a binding does not inc refs on source and target (they are weak
583 # on the binding object itself)
584 self.assertEqual(self.source.__grefcount__, 1)
585 self.assertEqual(self.target.__grefcount__, 1)
587 # Use GObject.get_property because the "props" accessor leaks.
588 # Note property names are canonicalized.
589 self.assertEqual(binding.get_property('source'), self.source)
590 self.assertEqual(binding.get_property('source_property'), 'int-prop')
591 self.assertEqual(binding.get_property('target'), self.target)
592 self.assertEqual(binding.get_property('target_property'), 'int-prop')
593 self.assertEqual(binding.get_property('flags'), GObject.BindingFlags.DEFAULT)
595 # Delete reference to source or target and the binding will remove its own
596 # "self reference".
597 ref = self.source.weak_ref()
598 del self.source
599 gc.collect()
600 self.assertEqual(ref(), None)
601 self.assertEqual(binding.__grefcount__, 1)
603 # Finally clear out the last ref held by the python wrapper
604 ref = binding.weak_ref()
605 del binding
606 gc.collect()
607 self.assertEqual(ref(), None)
610 class TestGValue(unittest.TestCase):
611 def test_type_constant(self):
612 self.assertEqual(GObject.TYPE_VALUE, GObject.Value.__gtype__)
613 self.assertEqual(GObject.type_name(GObject.TYPE_VALUE), 'GValue')
615 def test_no_type(self):
616 value = GObject.Value()
617 self.assertEqual(value.g_type, GObject.TYPE_INVALID)
618 self.assertRaises(TypeError, value.set_value, 23)
619 self.assertEqual(value.get_value(), None)
621 def test_int(self):
622 value = GObject.Value(GObject.TYPE_UINT)
623 self.assertEqual(value.g_type, GObject.TYPE_UINT)
624 value.set_value(23)
625 self.assertEqual(value.get_value(), 23)
626 value.set_value(42.0)
627 self.assertEqual(value.get_value(), 42)
629 def test_string(self):
630 value = GObject.Value(str, 'foo_bar')
631 self.assertEqual(value.g_type, GObject.TYPE_STRING)
632 self.assertEqual(value.get_value(), 'foo_bar')
634 def test_float(self):
635 # python float is G_TYPE_DOUBLE
636 value = GObject.Value(float, 23.4)
637 self.assertEqual(value.g_type, GObject.TYPE_DOUBLE)
638 value.set_value(1e50)
639 self.assertAlmostEqual(value.get_value(), 1e50)
641 value = GObject.Value(GObject.TYPE_FLOAT, 23.4)
642 self.assertEqual(value.g_type, GObject.TYPE_FLOAT)
643 self.assertRaises(TypeError, value.set_value, 'string')
644 self.assertRaises(OverflowError, value.set_value, 1e50)
646 def test_float_inf_nan(self):
647 nan = float('nan')
648 for type_ in [GObject.TYPE_FLOAT, GObject.TYPE_DOUBLE]:
649 for x in [float('inf'), float('-inf'), nan]:
650 value = GObject.Value(type_, x)
651 # assertEqual() is False for (nan, nan)
652 if x is nan:
653 self.assertEqual(str(value.get_value()), 'nan')
654 else:
655 self.assertEqual(value.get_value(), x)
657 def test_enum(self):
658 value = GObject.Value(GLib.FileError, GLib.FileError.FAILED)
659 self.assertEqual(value.get_value(), GLib.FileError.FAILED)
661 def test_flags(self):
662 value = GObject.Value(GLib.IOFlags, GLib.IOFlags.IS_READABLE)
663 self.assertEqual(value.get_value(), GLib.IOFlags.IS_READABLE)
665 def test_object(self):
666 class TestObject(GObject.Object):
667 pass
668 obj = TestObject()
669 value = GObject.Value(GObject.TYPE_OBJECT, obj)
670 self.assertEqual(value.get_value(), obj)
672 def test_value_array(self):
673 value = GObject.Value(GObject.ValueArray)
674 self.assertEqual(value.g_type, GObject.type_from_name('GValueArray'))
675 value.set_value([32, 'foo_bar', 0.3])
676 self.assertEqual(value.get_value(), [32, 'foo_bar', 0.3])
678 if __name__ == '__main__':
679 unittest.main()