Skip to content

fix(detection): index list data with a list of booleans as a mask - #2737

Open
MohammadHijjawi97 wants to merge 2 commits into
roboflow:developfrom
MohammadHijjawi97:fix/detections-boolean-list-index
Open

MohammadHijjawi97 wants to merge 2 commits into
roboflow:developfrom
MohammadHijjawi97:fix/detections-boolean-list-index

Conversation

@MohammadHijjawi97

Copy link
Copy Markdown
Contributor

Description

Detections.__getitem__ accepts a list of booleans as a mask: NumPy selects the matching rows of xyxy, mask, confidence, class_id, tracker_id and every array in data. List values in data are a supported type, but get_data_item read the same list as positions, so True and False became the indices 1 and 0. Depending on the mask this gave wrong data, a ValueError, or a TypeError.

import numpy as np
import supervision as sv

detections = sv.Detections(
    xyxy=np.array([[0, 0, 10, 10], [20, 20, 30, 30], [40, 40, 50, 50]], dtype=float),
    class_id=np.array([0, 1, 0]),
    data={"label": ["cat", "dog", "bird"]},
)
for index in ([True, True, True], [True, False, True], [c == 0 for c in detections.class_id]):
    print(detections[index].data["label"])

On develop:

['dog', 'dog', 'dog']
ValueError: Length of list for key 'label' must be 2
TypeError: list indices must be integers or slices, not numpy.bool

With this change:

['cat', 'dog', 'bird']
['cat', 'bird']
['cat', 'bird']

Motivation and Context

Filtering with a list comprehension, such as detections[[c in wanted for c in detections.class_id]], is a common way to select detections. With list-valued data it silently scrambled labels when every element was True, and failed otherwise. The array fields of the same Detections were already selected correctly, so only the list data was out of step.

Changes Made

  • get_data_item: for a Python list index, list data now takes the positions NumPy resolves for that index (np.arange(len(value))[index]). A list of booleans, including np.bool_ elements, now acts as a mask, as it does for the array fields. Integer lists, negative indices and out-of-range errors behave as before.
  • Slice, integer and np.ndarray indices are unchanged.
  • Added TestDetectionsSelectBooleanList in tests/detection/test_core.py.

Testing

  • pytest tests/detection/test_core.py -k BooleanList: all 4 cases fail on develop and pass with this change.

  • pytest tests: 5603 passed, 1 skipped.

  • pytest --doctest-modules src/supervision/detection/core.py src/supervision/detection/utils/internal.py: 16 passed.

  • pre-commit run --files on the changed files: ruff, ruff-format, docformatter and codespell pass. mypy reports no errors in the changed files.

  • Added/updated tests, and the full suite passes locally

  • Updated docs (docstrings / mkdocs entry) for new or changed public API

  • Added a changelog entry in docs/changelog.md under Unreleased (skip for lint/type/format-only or pure doc changes)

Additional Notes

KeyPoints uses the same helper, so list data in KeyPoints.data gets the same fix.

`Detections[[True, False, True]]` selects rows 0 and 2 of every array field,
because NumPy reads a list of booleans as a mask, but `get_data_item` read
the same list as positions for list-valued `data`: `True` and `False` became
the indices 1 and 0. An all-True mask therefore returned the second item for
every row, any other mask failed with a length error, and a list of
`np.bool_` values, as from `[c == 0 for c in detections.class_id]`, raised
`TypeError`.

List data now takes the positions NumPy resolves for the same index.
@Borda Borda added the bug Something isn't working label Oct 15, 2026
@Borda
Borda requested a balanced review from Copilot October 15, 2026 17:59

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Single-row selections now allocate full-length position arrays, introducing quadratic work when smoothing detections with list-valued data.

1 open finding
What changed in this PR

Fixes boolean-list indexing so list-valued detection metadata stays aligned with NumPy array fields.

Changes:

  • Resolves list indices through NumPy.
  • Adds regression tests for mixed, all-true, all-false, and NumPy boolean masks.
  • Documents the fix in the changelog.
File Description
tests/​detection/​test_core.py Adds boolean-list selection tests.
src/​supervision/​detection/​utils/​internal.py Corrects mask handling for list-valued data.
docs/​changelog.md Documents corrected selection behavior.

🧠 Review effort: Balanced


💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +765 to +768
# Resolve the positions as NumPy indexes the array fields, so a
# list of booleans is a mask, not the positions 0 and 1.
positions = np.arange(len(value))[index]
subset_data[key] = [value[i] for i in positions]
@Borda Borda added enhancement New feature or request and removed bug Something isn't working labels Oct 15, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request has conflicts

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants