Skip to content

Commit

Permalink
Fix ValueError check in ColumnDataSource.patch (bokeh#14020)
Browse files Browse the repository at this point in the history
* Fix ValueError check in ColumnDataSource.patch

* Use f-string in src/bokeh/models/sources.py

* Add TestColumnDataSource::test_bad_multi_index
  • Loading branch information
cdeil authored Aug 14, 2024
1 parent d55ea6a commit 42435cd
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 4 deletions.
8 changes: 4 additions & 4 deletions src/bokeh/models/sources.py
Original file line number Diff line number Diff line change
Expand Up @@ -682,13 +682,13 @@ def patch(self, patches: Patches, setter: Setter | None = None) -> None:
# integer index, patch single value of 1d column
if isinstance(ind, int):
if ind > col_len or ind < 0:
raise ValueError("Out-of bounds index (%d) in patch for column: %s" % (ind, name))
raise ValueError(f"Out-of bounds index ({ind}) in patch for column: {name}")

# slice index, patch multiple values of 1d column
elif isinstance(ind, slice):
_check_slice(ind)
if ind.stop is not None and ind.stop > col_len:
raise ValueError("Out-of bounds slice index stop (%d) in patch for column: %s" % (ind.stop, name))
raise ValueError(f"Out-of bounds slice index stop ({ind.stop}) in patch for column: {name}")

# multi-index, patch sub-regions of "n-d" column
elif isinstance(ind, list | tuple):
Expand All @@ -703,7 +703,7 @@ def patch(self, patches: Patches, setter: Setter | None = None) -> None:
raise ValueError(f"Initial patch sub-index may only be integer, got: {ind_0}")

if ind_0 > col_len or ind_0 < 0:
raise ValueError("Out-of bounds initial sub-index (%d) in patch for column: %s" % (ind, name))
raise ValueError(f"Out-of bounds initial sub-index ({ind_0}) in patch for column: {name}")

if not isinstance(self.data[name][ind_0], np.ndarray):
raise ValueError("Can only sub-patch into columns with NumPy array items")
Expand All @@ -714,7 +714,7 @@ def patch(self, patches: Patches, setter: Setter | None = None) -> None:
elif isinstance(ind_0, slice):
_check_slice(ind_0)
if ind_0.stop is not None and ind_0.stop > col_len:
raise ValueError("Out-of bounds initial slice sub-index stop (%d) in patch for column: %s" % (ind.stop, name))
raise ValueError(f"Out-of bounds initial slice sub-index stop ({ind_0.stop}) in patch for column: {name}")

# Note: bounds of sub-indices after the first are not checked!
for subind in ind[1:]:
Expand Down
14 changes: 14 additions & 0 deletions tests/unit/bokeh/models/test_sources.py
Original file line number Diff line number Diff line change
Expand Up @@ -742,6 +742,20 @@ def test_patch_bad_slice_indices(self) -> None:
with pytest.raises(ValueError, match=r"Patch slices must have non-negative \(start, stop, step\) values, got slice\(1, 10, -1\)"):
ds.patch(dict(a=[(slice(1, 10, -1), list(range(10)))]))

def test_bad_multi_index(self) -> None:
ds = ColumnDataSource(data=dict(foo=[1]))
with pytest.raises(ValueError, match=r"Empty \(length zero\) patch multi-index"):
ds.patch(dict(foo=[[[], 5]]))
with pytest.raises(ValueError, match=r"Patch multi-index must contain more than one subindex"):
ds.patch(dict(foo=[[[2], 5]]))
with pytest.raises(ValueError, match=r"Initial patch sub-index may only be integer, got: spam"):
ds.patch(dict(foo=[[["spam", 3], 5]]))
with pytest.raises(ValueError, match=r"Out-of bounds initial sub-index \(-1\) in patch for column: foo"):
ds.patch(dict(foo=[[[-1, 3], 5]]))
with pytest.raises(ValueError, match=r"Can only sub-patch into columns with NumPy array items"):
ds.patch(dict(foo=[[[0, 3], 5]]))
with pytest.raises(ValueError, match=r"Invalid patch index: {}"):
ds.patch(dict(foo=[[{}, 5]]))

def test_patch_good_slice_indices(self) -> None:
ds = bms.ColumnDataSource(data=dict(a=[10, 11, 12, 13, 14, 15], b=[20, 21, 22, 23, 24, 25]))
Expand Down

0 comments on commit 42435cd

Please sign in to comment.