Describe the bug
proximity, allocation, and direction accept a target_values list. When that list contains a non-finite value such as np.inf, the backends disagree on whether those values count as targets.
On NumPy, _is_target_value (xrspatial/proximity.py:346) checks only v == target_values[k] for explicit targets, with no finiteness guard. A pixel holding inf matches target_values=[np.inf], so the search runs and returns full output.
On CuPy (proximity.py:516-518) and Dask (_target_mask, proximity.py:780-784), the mask is isin(data, target_values) & isfinite(data). The finiteness term drops inf pixels even when the user asked for them explicitly. With no surviving targets the kernels fill the result with NaN.
So the same raster and the same target_values=[np.inf] returns a real distance/allocation/direction grid on NumPy and an all-NaN grid on Dask and CuPy.
Expected behavior
One behavior across all four backends: numpy, cupy, dask+numpy, dask+cupy.
A non-finite target_values entry (inf, -inf, nan) is not a meaningful raster category. nan can never match a pixel anyway because nan == nan is False, and inf only "matches" on NumPy by accident. The fix should reject non-finite target_values up front with a clear ValueError, consistent with how the function already validates distance_metric and max_distance. The empty-target_values default path, which already ignores non-finite pixels on every backend, stays unchanged.
Additional context
Refs: xrspatial/proximity.py:346, xrspatial/proximity.py:516, xrspatial/proximity.py:780. Central dispatch is _process (proximity.py:1152), which already normalizes target_values with np.asarray and is the natural place for the check.
Describe the bug
proximity,allocation, anddirectionaccept atarget_valueslist. When that list contains a non-finite value such asnp.inf, the backends disagree on whether those values count as targets.On NumPy,
_is_target_value(xrspatial/proximity.py:346) checks onlyv == target_values[k]for explicit targets, with no finiteness guard. A pixel holdinginfmatchestarget_values=[np.inf], so the search runs and returns full output.On CuPy (proximity.py:516-518) and Dask (
_target_mask, proximity.py:780-784), the mask isisin(data, target_values) & isfinite(data). The finiteness term dropsinfpixels even when the user asked for them explicitly. With no surviving targets the kernels fill the result with NaN.So the same raster and the same
target_values=[np.inf]returns a real distance/allocation/direction grid on NumPy and an all-NaN grid on Dask and CuPy.Expected behavior
One behavior across all four backends: numpy, cupy, dask+numpy, dask+cupy.
A non-finite
target_valuesentry (inf, -inf, nan) is not a meaningful raster category.nancan never match a pixel anyway becausenan == nanis False, andinfonly "matches" on NumPy by accident. The fix should reject non-finitetarget_valuesup front with a clear ValueError, consistent with how the function already validatesdistance_metricandmax_distance. The empty-target_valuesdefault path, which already ignores non-finite pixels on every backend, stays unchanged.Additional context
Refs: xrspatial/proximity.py:346, xrspatial/proximity.py:516, xrspatial/proximity.py:780. Central dispatch is
_process(proximity.py:1152), which already normalizestarget_valueswithnp.asarrayand is the natural place for the check.