8 from gi
.repository
import GObject
, GLib
9 from gi
import PyGIDeprecationWarning
10 from gi
.module
import get_introspection_module
13 _gobject
= gi
._gi
._gobject
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.*'):
39 with self
.assertRaisesRegex(RuntimeError, 'This method is currently unsupported.*'):
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.
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()
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)
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.
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()
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)
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.
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()
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)
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.
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()
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)
216 self
.assertEqual(obj
.__grefcount
__, 1)
218 def test_uninitialized_object(self
):
219 class Obj(GObject
.GObject
):
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
):
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
):
249 self
.assertEqual(sys
.getrefcount(obj
), 2)
251 def test_new_subclass_instance_has_two_refs_using_gobject_new(self
):
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
))
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.
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.
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
389 with self
.obj
.freeze_notify():
390 self
.obj
.props
.prop
= 1
391 self
.assertEqual(self
.tracking
, [])
392 raise ValueError('Simulation')
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
407 with self
.obj
.handler_block(self
.handler
):
408 self
.obj
.props
.prop
= 1
409 self
.assertEqual(self
.tracking
, [])
410 raise ValueError('Simulation')
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)
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')
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)
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
):
502 def transform_to(binding
, value
, user_data
=None):
503 self
.assertEqual(user_data
, test_data
)
506 def transform_from(binding
, value
, user_data
=None):
507 self
.assertEqual(user_data
, test_data
)
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
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
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
597 ref
= self
.source
.weak_ref()
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()
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)
622 value
= GObject
.Value(GObject
.TYPE_UINT
)
623 self
.assertEqual(value
.g_type
, GObject
.TYPE_UINT
)
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
):
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)
653 self
.assertEqual(str(value
.get_value()), 'nan')
655 self
.assertEqual(value
.get_value(), x
)
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
):
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__':