Skip to content

Commit fa829c3

Browse files
Validate empty seed dataset criteria (#2967)
Signed-off-by: Ray Winkelman <rwinkelman@users.noreply.github.com> Co-authored-by: Ray Winkelman <rwinkelman@users.noreply.github.com> Co-authored-by: hannahwestra25 <hannahwestra@microsoft.com>
1 parent 3f729ac commit fa829c3

2 files changed

Lines changed: 22 additions & 8 deletions

File tree

‎pyrit/datasets/seed_datasets/seed_metadata.py‎

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,8 @@ class SeedDatasetFilter:
184184
SeedDatasetMetadata(size={"large"}, modalities={"image"}),
185185
])
186186
187-
Passing both flat kwargs and criteria raises ValueError.
187+
Passing both flat kwargs and criteria raises ValueError, as does passing an
188+
empty criteria list. Omit `criteria` entirely for an unfiltered match-all filter.
188189
189190
Special tags:
190191
- "all": Returns every dataset, ignores all other fields. This tag will
@@ -193,7 +194,7 @@ class SeedDatasetFilter:
193194
strict_match=True, loses its shortcut and is treated as a normal tag.
194195
195196
Args:
196-
criteria: Explicit list of SeedDatasetMetadata to OR-match against.
197+
criteria: Explicit non-empty list of SeedDatasetMetadata to OR-match against.
197198
strict_match: If True, within-axis matching uses AND (all filter values
198199
must be present) instead of OR (any overlap suffices).
199200
**kwargs: Flat metadata fields (tags, size, modalities, etc.) for simple use.
@@ -221,12 +222,13 @@ def __init__(
221222
])
222223
223224
Args:
224-
criteria: Explicit list of SeedDatasetMetadata to OR-match against.
225+
criteria: Explicit non-empty list of SeedDatasetMetadata to OR-match against.
225226
strict_match: If True, within-axis matching uses AND instead of OR.
226227
**kwargs: Flat metadata fields passed to SeedDatasetMetadata.
227228
228229
Raises:
229-
ValueError: If both criteria and flat kwargs are provided.
230+
ValueError: If both criteria and flat kwargs are provided, or if an
231+
explicit criteria list is empty.
230232
"""
231233
if criteria is not None and kwargs:
232234
raise ValueError("Cannot pass both 'criteria' and flat metadata kwargs. Use one or the other.")
@@ -256,11 +258,19 @@ def _validate(self) -> None:
256258
Warn about contradictory filter configurations.
257259
258260
Raises:
259-
ValueError: If a criterion requests a filter axis with an empty set, or if
260-
strict_match is True and any criterion has multiple values for a singular
261-
field (size, source_type). Both checks are skipped when any criterion
262-
carries the 'all' tag, since 'all' bypasses every other field.
261+
ValueError: If the criteria list is empty, if a criterion requests a filter
262+
axis with an empty set, or if strict_match is True and any criterion has
263+
multiple values for a singular field (size, source_type). The latter two
264+
checks are skipped when any criterion carries the 'all' tag, since 'all'
265+
bypasses every other field.
263266
"""
267+
# Only an explicit `criteria=[]` reaches here; the kwargs and no-arg branches
268+
# always produce exactly one criterion. An empty list would make the `any(...)`
269+
# over criteria in _match_filter_to_metadata vacuously False, so the filter
270+
# would silently match no dataset at all.
271+
if not self.criteria:
272+
raise ValueError("'criteria' must contain at least one metadata criterion.")
273+
264274
# An empty set is not a filter. Without strict_match nothing can overlap with it,
265275
# and with strict_match nothing can be outside it, so the same filter would match
266276
# either no dataset at all or every dataset, depending on one flag. None is how a

‎tests/unit/datasets/test_seed_dataset_metadata.py‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ def test_has_no_values(self):
5858
assert c.tags is None
5959
assert c.size is None
6060

61+
def test_empty_criteria_fails(self):
62+
with pytest.raises(ValueError, match="criteria.*at least one"):
63+
SeedDatasetFilter(criteria=[])
64+
6165
def test_has_some_values(self):
6266
f = SeedDatasetFilter(size={"large"})
6367
assert f.criteria[0].size == {"large"}

0 commit comments

Comments
 (0)