Skip to content

Commit ce3b2e0

Browse files
authored
fix: Handle NdMapping with explicit tuple set slicing with dimension values (#6780)
1 parent 2e57026 commit ce3b2e0

4 files changed

Lines changed: 72 additions & 0 deletions

File tree

holoviews/core/ndmapping.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,12 @@ def _split_index(self, key):
227227
elif key == ():
228228
return (), ()
229229

230+
# If a single set/list of full-key tuples, expand into per-dimension sets
231+
if len(key) == 1 and isinstance(key[0], (set, list)) and len(key[0]) > 0:
232+
items = list(key[0])
233+
if all(isinstance(item, tuple) and len(item) == self.ndims for item in items):
234+
key = tuple([item[i] for item in items] for i in range(self.ndims))
235+
230236
if key[0] is Ellipsis:
231237
num_pad = self.ndims - len(key) + 1
232238
key = (slice(None),) * num_pad + key[1:]

holoviews/core/spaces.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1242,6 +1242,8 @@ def _cross_product(self, tuple_key, cache, data_slice):
12421242
val = cache[key]
12431243
else:
12441244
val = self._execute_callback(*key)
1245+
if not self.unbounded:
1246+
self._cache(key, val)
12451247
if data_slice:
12461248
val = self._dataslice(val, data_slice)
12471249
data.append((key, val))

holoviews/tests/core/test_dynamic.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,40 @@ def cb(i):
496496
with pytest.raises(KeyError):
497497
dmaps[1][1]
498498

499+
@pytest.mark.parametrize(
500+
("kdims", "keys"),
501+
[
502+
([hv.Dimension("x", values=[1, 2]), "y"], {(1, 0.5)}),
503+
([hv.Dimension("x", values=["1", "2"]), "y"], {("1", 0.5)}),
504+
([hv.Dimension("x", range=(1, 5)), "y"], {(1, 0.5)}),
505+
(
506+
[hv.Dimension("x", values=[1, 2]), hv.Dimension("y", values=[3, 4])],
507+
{(1, 3), (2, 4)},
508+
),
509+
],
510+
ids=["int_values", "str_values", "no_values", "multi_key"],
511+
)
512+
def test_explicit_tuple_set_slicing(self, kdims, keys):
513+
call_count = 0
514+
515+
def callback(x, y):
516+
nonlocal call_count
517+
call_count += 1
518+
return hv.Curve([x, y])
519+
520+
dmap = hv.DynamicMap(callback, kdims=kdims)
521+
assert call_count == 0
522+
result = dmap[keys]
523+
assert len(result) == len(keys)
524+
for key in keys:
525+
assert key in result.data
526+
527+
assert call_count == len(keys)
528+
529+
# Check we hit cache
530+
result = dmap[keys]
531+
assert call_count == len(keys)
532+
499533

500534
class DynamicMapOptionsTests(CustomBackendTestCase):
501535
def test_dynamic_options(self):

holoviews/tests/core/test_ndmapping.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from __future__ import annotations
22

33
import numpy as np
4+
import pytest
45

56
import holoviews as hv
67
from holoviews.core.ndmapping import MultiDimensionalMapping, UniformNdMapping
@@ -127,6 +128,35 @@ def test_ndmapping_slice_upper_bound_exclusive2_float(self):
127128
ndmap = hv.NdMapping(self.init_item_odict, kdims=[self.dim1, self.dim2])
128129
assert ndmap[:, 0.0:3.0].keys() == [(1, 2.0)]
129130

131+
@pytest.mark.parametrize(
132+
("kdims", "data", "keys"),
133+
[
134+
([hv.Dimension("x", values=[1, 2]), "y"], {(1, 0.5): "a", (2, 0.5): "b"}, {(1, 0.5)}),
135+
(
136+
[hv.Dimension("x", values=["1", "2"]), "y"],
137+
{("1", 0.5): "a", ("2", 0.5): "b"},
138+
{("1", 0.5)},
139+
),
140+
(
141+
["x", hv.Dimension("y", values=[0.5, 1.5])],
142+
{(1, 0.5): "a", (1, 1.5): "b"},
143+
{(1, 0.5)},
144+
),
145+
(
146+
[hv.Dimension("x", values=[1, 2]), "y"],
147+
{(1, 0.5): "a", (2, 0.5): "b"},
148+
{(1, 0.5), (2, 0.5)},
149+
),
150+
],
151+
ids=["int_values_first", "str_values_first", "int_values_on_second", "multi_key"],
152+
)
153+
def test_explicit_tuple_set_slicing(self, kdims, data, keys):
154+
ndmap = hv.NdMapping(data, kdims=kdims)
155+
result = ndmap[keys]
156+
assert len(result) == len(keys)
157+
for key in keys:
158+
assert key in result.data
159+
130160
def test_idxmapping_unsorted(self):
131161
data = [("B", 1), ("C", 2), ("A", 3)]
132162
ndmap = MultiDimensionalMapping(data, sort=False)

0 commit comments

Comments
 (0)