##// END OF EJS Templates
add HasTraits.delay_trait_notifications...
Min RK -
Show More
@@ -1330,6 +1330,50 b' def test_pickle_hastraits():'
1330 nt.assert_equal(c2.i, c.i)
1330 nt.assert_equal(c2.i, c.i)
1331 nt.assert_equal(c2.j, c.j)
1331 nt.assert_equal(c2.j, c.j)
1332
1332
1333
1334 class OrderTraits(HasTraits):
1335 notified = Dict()
1336
1337 a = Unicode()
1338 b = Unicode()
1339 c = Unicode()
1340 d = Unicode()
1341 e = Unicode()
1342 f = Unicode()
1343 g = Unicode()
1344 h = Unicode()
1345 i = Unicode()
1346 j = Unicode()
1347 k = Unicode()
1348 l = Unicode()
1349
1350 def _notify(self, name, old, new):
1351 """check the value of all traits when each trait change is triggered
1352
1353 This verifies that the values are not sensitive
1354 to dict ordering when loaded from kwargs
1355 """
1356 # check the value of the other traits
1357 # when a given trait change notification fires
1358 self.notified[name] = {
1359 c: getattr(self, c) for c in 'abcdefghijkl'
1360 }
1361
1362 def __init__(self, **kwargs):
1363 self.on_trait_change(self._notify)
1364 super(OrderTraits, self).__init__(**kwargs)
1365
1366 def test_notification_order():
1367 d = {c:c for c in 'abcdefghijkl'}
1368 obj = OrderTraits()
1369 nt.assert_equal(obj.notified, {})
1370 obj = OrderTraits(**d)
1371 notifications = {
1372 c: d for c in 'abcdefghijkl'
1373 }
1374 nt.assert_equal(obj.notified, notifications)
1375
1376
1333 class TestEventful(TestCase):
1377 class TestEventful(TestCase):
1334
1378
1335 def test_list(self):
1379 def test_list(self):
@@ -575,8 +575,31 b' class HasTraits(py3compat.with_metaclass(MetaHasTraits, object)):'
575 # Allow trait values to be set using keyword arguments.
575 # Allow trait values to be set using keyword arguments.
576 # We need to use setattr for this to trigger validation and
576 # We need to use setattr for this to trigger validation and
577 # notifications.
577 # notifications.
578 for key, value in iteritems(kw):
578
579 setattr(self, key, value)
579 with self.delay_trait_notifications():
580 for key, value in iteritems(kw):
581 setattr(self, key, value)
582
583 @contextlib.contextmanager
584 def delay_trait_notifications(self):
585 """Context manager for bundling trait change notifications
586
587 Use this when doing multiple trait assignments (init, config),
588 to avoid race conditions in trait notifiers requesting other trait values.
589 All trait notifications will fire after all values have been assigned.
590 """
591 _notify_trait = self._notify_trait
592 notifications = []
593 self._notify_trait = lambda *a: notifications.append(a)
594
595 try:
596 yield
597 finally:
598 self._notify_trait = _notify_trait
599
600 # trigger delayed notifications
601 for args in notifications:
602 self._notify_trait(*args)
580
603
581 def _notify_trait(self, name, old_value, new_value):
604 def _notify_trait(self, name, old_value, new_value):
582
605
General Comments 0
You need to be logged in to leave comments. Login now