relabel_sequential() fails for every unsigned dtype: OverflowError: Python integer -1 out of bounds for uint16
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 394
- Forks
- 95
- Avg merge
- 4d 3h
- Merged PRs (30d)
- 7
Description
[!NOTE]
This whole message is AI-generated. The issue was automatically discovered and reported by an AI agent (Claude) during an autonomous bug hunt on thespatialdatacode base. It has not been verified or triaged by a human yet; theneeds: triagelabel is set so that a maintainer can confirm it. The reproduction script below was executed by the agent in an isolated environment (see Environment) and its output is pasted verbatim.
Summary
With NumPy ≥ 2 the Python int -1 cannot be cast to an unsigned dtype (NEP 50), so relabel_sequential raises for uint8/16/32/64 inputs and works only for signed dtypes. Reproduced with numpy 2.4.4 and 2.5.3.
Severity (agent's assessment): high — segmentation masks are almost always unsigned, and map_raster(relabel=True) points users to this function
Where: src/spatialdata/_core/operations/map.py::relabel_sequential (da.full(max_label + 1, -1, dtype=arr.dtype))
Expected behaviour
Works for all integer dtypes.
Reproduction
Save as repro.py and run uv run repro.py (the PEP 723 header pins spatialdata to the commit the bug was found on; replace the URL fragment with @main to test the current main branch).
# /// script
# requires-python = ">=3.12"
# dependencies = [
# "spatialdata @ git+https://github.com/scverse/spatialdata.git@ccf1ea048d054b6624214bf618008a9f9ae223e0",
# ]
# ///
"""relabel_sequential fails for every unsigned dtype (numpy 2: -1 cannot be cast to uintN)."""
import warnings
import numpy as np
import dask.array as da
from spatialdata import relabel_sequential
warnings.simplefilter("ignore")
print("numpy", np.__version__)
bug = False
for dt in [np.uint8, np.uint16, np.uint32, np.int32, np.int64]:
arr = da.from_array(np.array([[0, 5, 9], [9, 5, 0]], dtype=dt), chunks=(2, 3))
try:
print(f"{dt.__name__:7s}: {relabel_sequential(arr).compute().tolist()}")
except Exception as e: # noqa: BLE001
print(f"{dt.__name__:7s}: {type(e).__name__}: {e}")
bug = True
print("VERDICT:", "BUG REPRODUCED" if bug else "NOT REPRODUCED")
Observed output
numpy 2.5.3
uint8 : OverflowError: Python integer -1 out of bounds for uint8
uint16 : OverflowError: Python integer -1 out of bounds for uint16
uint32 : OverflowError: Python integer -1 out of bounds for uint32
int32 : [[0, 1, 2], [2, 1, 0]]
int64 : [[0, 1, 2], [2, 1, 0]]
VERDICT: BUG REPRODUCED
Possible fix direction (unverified)
Use a fill value valid for the dtype (0, since ids not in unique_labels are background anyway, or np.iinfo(dtype).max) and add unsigned-dtype tests. Note also that the lookup array must be a single dask chunk (rechunk(-1)) for the following map_blocks(operator.getitem, ...) to be correct when max_label is very large.
Environment
uv run repro.py with the PEP 723 metadata in the script (fresh, isolated environment; spatialdata built from main @ ccf1ea0 (2026-08-28); Python 3.13, latest releases of the dependencies at run time: pandas 3.0, anndata 0.13, zarr 3.3, dask 2026.8, numpy 2.5, geopandas 1.1, shapely 2.1). macOS (arm64). Also reproduced in a second environment with pandas 2.3.3 / anndata 0.12.11 / numpy 2.4.4 / zarr 3.2.1.
Automatically generated; discovered by an AI agent (Claude) and not yet reviewed by a human.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in src/spatialdata/_core/operations/map.py at relabel_sequential and run the provided repro.py script with the listed unsigned dtypes. Add regression coverage for uint8, uint16, uint32, and uint64 inputs, then verify that relabel_sequential produces the expected labels for unsigned and signed integer arrays.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- numpy, python
- Domain
- data
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 76/100