diff --git a/ipywidgets/widgets/tests/test_set_state.py b/ipywidgets/widgets/tests/test_set_state.py index b580941c97..f59c619445 100644 --- a/ipywidgets/widgets/tests/test_set_state.py +++ b/ipywidgets/widgets/tests/test_set_state.py @@ -122,4 +122,4 @@ def test_set_state_data_truncate(): # Sanity: assert len(buffers) == 1 - assert buffers[0].tobytes() == data[:20].tobytes() + assert buffers[0] == data[:20].tobytes() diff --git a/ipywidgets/widgets/widget.py b/ipywidgets/widgets/widget.py index 014a4b60cb..4b523d72de 100644 --- a/ipywidgets/widgets/widget.py +++ b/ipywidgets/widgets/widget.py @@ -483,7 +483,7 @@ def _compare(self, a, b): else: return a == b - def _compare_buffers(self, a, b, key): + def _buffer_list_equal(self, a, b): """Compare two lists of buffers for equality. Used to decide whether two sequences of buffers (memoryviews) differ, @@ -501,7 +501,9 @@ def _compare_buffers(self, a, b, key): # e.g. memoryview(np.frombuffer(ia, dtype='float32')) != # memoryview(np.frombuffer(b)), since the format info differs. # However, since we only transfer bytes, we use `tobytes()`. - if ia.tobytes() != ib.tobytes(): + iabytes = ia.tobytes() if isinstance(ia, memoryview) else ia + ibbytes = ib.tobytes() if isinstance(ib, memoryview) else ib + if ia != ib: return False return True @@ -620,13 +622,14 @@ def _should_send_property(self, key, value): # idiosyncracies of how python data structures map to json, for example # tuples get converted to lists. if key in self._property_lock: + # model_state, buffer_paths, buffers split_value = _remove_buffers({ key: to_json(value, self)}) split_lock = _remove_buffers({ key: self._property_lock[key]}) # Compare state and buffer_paths - if jsondumps(split_value[:2]) == jsondumps(split_lock[:2]): - # Compare buffers - if self._compare_buffers(split_value[2], split_lock[2], key): - return False + if (jsonloads(jsondumps(split_value[0])) == jsonloads(jsondumps(split_lock[0])) + and split_value[1] == split_lock[1] + and self._buffer_list_equal(split_value[2], split_lock[2])): + return False if self._holding_sync: self._states_to_send.add(key) return False