Skip to content

Commit

Permalink
Ensure TraitListEvent.index is always an integer (#548)
Browse files Browse the repository at this point in the history
* Regression test for bug

* fix

* Ensure that the TraitListEvent.index is always an integer.
  • Loading branch information
mdickinson authored Nov 11, 2019
1 parent c602b70 commit 010b774
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 3 deletions.
27 changes: 27 additions & 0 deletions traits/tests/test_sync_traits.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,33 @@ def test_sync_lists(self):
with self.assertTraitDoesNotChange(a, "l"):
b.l = [7, 8]

def test_sync_lists_partial_slice(self):
""" Test synchronization of list traits when there is a partial slice.
Regression test for enthought/traits#540
"""

a = A()
b = B()

a.sync_trait("l", b)

# Change entire list.
a.l = [1, 2, 3]
self.assertEqual(a.l, b.l)
b.l = [4, 5]
self.assertEqual(a.l, b.l)

# Change list items with an empty slice.
with self.assertTraitChanges(b, "l_items"):
a.l[:] = [7]
self.assertEqual(b.l, [7])

# Change list items with a partial slice.
with self.assertTraitChanges(b, "l_items"):
a.l[:0] = [6]
self.assertEqual(b.l, [6, 7])

def test_sync_delete(self):
""" Test that deleting a synchronized trait works.
"""
Expand Down
12 changes: 11 additions & 1 deletion traits/tests/test_traits.py
Original file line number Diff line number Diff line change
Expand Up @@ -1337,8 +1337,10 @@ def test_trait_list_event(self):
self.assertLastTraitListEventEqual(3, [], [5])
self.obj.alist[0:2] = [6, 7]
self.assertLastTraitListEventEqual(0, [2, 3], [6, 7])
self.obj.alist[:2] = [4, 5]
self.assertLastTraitListEventEqual(0, [6, 7], [4, 5])
self.obj.alist[0:2:1] = [8, 9]
self.assertLastTraitListEventEqual(0, [6, 7], [8, 9])
self.assertLastTraitListEventEqual(0, [4, 5], [8, 9])
old_event = self.last_event
self.obj.alist[0:2:1] = [8, 9]
# If no values changed, no new TraitListEvent will be generated.
Expand All @@ -1352,6 +1354,14 @@ def test_trait_list_event(self):
self.obj.alist = [1, 2, 3, 4]
del self.obj.alist[2:4]
self.assertLastTraitListEventEqual(2, [3, 4], [])
self.obj.alist[:0] = [5, 6, 7, 8]
self.assertLastTraitListEventEqual(0, [], [5, 6, 7, 8])
del self.obj.alist[:2]
self.assertLastTraitListEventEqual(0, [5, 6], [])
del self.obj.alist[0:2]
self.assertLastTraitListEventEqual(0, [7, 8], [])
del self.obj.alist[:]
self.assertLastTraitListEventEqual(0, [1, 2], [])

def _record_trait_list_event(self, object, name, old, new):
self.last_event = new
Expand Down
4 changes: 2 additions & 2 deletions traits/trait_handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -2537,7 +2537,7 @@ def __setitem__(self, key, value):
# In this case, we return a TraitListEvent with an
# index=key.start and the removed and added lists as they
# are.
index = key.start
index = 0 if key.start is None else key.start
else:
# Otherwise, we have an extended slice which was handled,
# badly, by __setitem__ before. In this case, we return the
Expand Down Expand Up @@ -2594,7 +2594,7 @@ def __delitem__(self, key):
if step == 1:
# FIXME: See corresponding comment in __setitem__() for
# explanation.
index = key.start
index = 0 if key.start is None else key.start
else:
index = key
removed = [removed]
Expand Down

0 comments on commit 010b774

Please sign in to comment.