Repository: holoviz/holoviews (python)

Issue:
ValueError when updating polyline using PolyEdit tool
https://github.com/holoviz/holoviews/blob/53e904958d5c07b467b4d8ab3683c1c1df30263b/holoviews/plotting/bokeh/callbacks.py#L1410

When updating polyline using PolyEdit tool this line results in the following error: 

`ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()`

The reason for it is in case of EditTool value[2] is a list of numpy arrays, not a str, so quick fix would be to add extra condition to this elif:

`
elif (
    isinstance(values, list)
    and len(values) == 4
    and isinstance(values[2], str )  # Without this line bokeh failes to process updated polylines
    and values[2] in ("big", "little")
    and isinstance(values[3], list)
):
`


Pull request description:
fix: PolyEdit stream not synchronizes with CDS
Fixes #6532

In case of using PolyEdit tool value[2] is a list of lists or numpy arrays, not a str.

Patch:
diff --git a/holoviews/plotting/bokeh/callbacks.py b/holoviews/plotting/bokeh/callbacks.py
index c3d596d26..3f438b017 100644
--- a/holoviews/plotting/bokeh/callbacks.py
+++ b/holoviews/plotting/bokeh/callbacks.py
@@ -1407,6 +1407,7 @@ class CDSCallback(Callback):
             elif (
                 isinstance(values, list)
                 and len(values) == 4
+                and isinstance(values[2], str)
                 and values[2] in ("big", "little")
                 and isinstance(values[3], list)
             ):


Test patch:
diff --git a/holoviews/tests/plotting/bokeh/test_callbacks.py b/holoviews/tests/plotting/bokeh/test_callbacks.py
index 592e19b48..d24551b60 100644
--- a/holoviews/tests/plotting/bokeh/test_callbacks.py
+++ b/holoviews/tests/plotting/bokeh/test_callbacks.py
@@ -468,6 +468,31 @@ def test_msg_with_base64_array():
     assert np.equal(data_expected, data_after).all()
 
 
+def test_msg_with_polyedit_polyline():
+    # Account for issue seen in https://github.com/holoviz/holoviews/issues/6532
+    data_before = {
+        "xs": [
+            [10.0, 20.0, 30.0, 40.0],
+            np.array([10.0, 20.0, 30.0, 40.0]),
+            np.array([10.0, 20.0, 30.0, 40.0]),
+            np.array([10.0, 20.0, 30.0, 40.0])
+        ],
+        "ys": [
+            [10.0, 20.0, 30.0, 40.0],
+            np.array([10.0, 20.0, 30.0, 40.0]),
+            np.array([10.0, 20.0, 30.0, 40.0]),
+            np.array([10.0, 20.0, 30.0, 40.0])
+        ],
+        "color": ["#FF0000", "#FF0000", "#FF0000", "#FF0000"],
+        "line_color": ["#FF0000", "#FF0000", "#FF0000", "#FF0000"],
+        "line_width": np.array([2, 2, 2, 2]),
+    }
+    msg_before = {"data": data_before}
+    msg_after = CDSCallback(None, None, None)._process_msg(msg_before)
+    data_after = msg_after["data"]
+    assert np.equal(data_before, data_after).all()
+
+
 @pytest.mark.usefixtures('bokeh_backend')
 def test_rangexy_multi_yaxes():
     c1 = Curve(np.arange(100).cumsum(), vdims='y')