diff --git a/CHANGES.txt b/CHANGES.txt index ce1da8d1e..e04478487 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -116,3 +116,4 @@ Fixes * `TraitSetObject.copy` now returns a plain rather than an uninitialized `TraitSetObject` instance. (#97) * Fix cyclic garbage arising from dynamic trait change handlers. (#101) + * Fix error when trying to listen to traits using list bracket notation (#195) diff --git a/traits/tests/test_regression.py b/traits/tests/test_regression.py index 11eb9e49c..48dadc646 100644 --- a/traits/tests/test_regression.py +++ b/traits/tests/test_regression.py @@ -3,7 +3,7 @@ import sys from ..has_traits import HasTraits, Property, on_trait_change -from ..trait_types import Bool, DelegatesTo, Instance, Int +from ..trait_types import Bool, DelegatesTo, Instance, Int, List from ..testing.unittest_tools import unittest @@ -55,6 +55,16 @@ def _get_y(self): return self.obj.x +class ListUpdatesTest(HasTraits): + a = List + b = List + events_received = Int(0) + + @on_trait_change('a[], b[]') + def _receive_events(self): + self.events_received += 1 + + class TestRegression(unittest.TestCase): def test_default_value_for_no_cache(self): @@ -106,5 +116,17 @@ def test_no_leaking_notifiers(self): del presenter self.assertEqual(len(ctrait._notifiers(1)), 0) + def test_init_list_depends(self): + """ Using two lists with bracket notation in extended name notation + should not raise an error. + """ + list_test = ListUpdatesTest() + # Updates to list items and the list trait itself should be counted. + list_test.a.append(0) + list_test.b = [1, 2, 3] + list_test.b[0] = 0 + self.assertEqual(list_test.events_received, 3) + + if __name__ == '__main__': unittest.main() diff --git a/traits/traits_listener.py b/traits/traits_listener.py index eb09de9cd..54babdef0 100644 --- a/traits/traits_listener.py +++ b/traits/traits_listener.py @@ -1255,7 +1255,10 @@ def parse_item ( self, terminator ): return result if c == '[': - if (self.skip_ws == ']') and (self.skip_ws == terminator): + is_closing_bracket = (self.skip_ws == ']') + next_char = self.skip_ws + item_complete = (next_char == terminator or next_char == ',') + if is_closing_bracket and item_complete: self.backspace result.is_list_handler = True else: