Describe the bug
contours() in xrspatial/contour.py does not validate its input raster before processing. Unlike sibling functions (curvature, morphology, sky_view_factor), it skips the standard _validate_raster() check from xrspatial.utils. Two problems follow:
-
A complex-dtype DataArray is accepted silently. Inside _contours_numpy, np.asarray(data, dtype=np.float64) casts the complex array to float64 and drops the imaginary part, emitting only a ComplexWarning. The function then returns contour lines traced on the real part instead of rejecting the input. _validate_raster() already rejects complex dtypes.
-
A non-DataArray input (e.g. a plain numpy array) fails late with a confusing error. Instead of a clear "must be an xarray.DataArray" message, it reaches ArrayTypeFunctionMapping and raises TypeError: Unsupported Array Type.
Expected behavior
contours() should validate its input up front: a ValueError for complex/non-numeric dtypes and a TypeError for non-DataArray inputs, matching the rest of the codebase.
Additional context
Found during a security sweep (dtype confusion). The fix is to call _validate_raster(agg, func_name='contours', name='agg', ndim=2) at the top of contours(). The silent complex-dtype path is the higher-severity half: it produces wrong results with no error.
Describe the bug
contours()inxrspatial/contour.pydoes not validate its input raster before processing. Unlike sibling functions (curvature,morphology,sky_view_factor), it skips the standard_validate_raster()check fromxrspatial.utils. Two problems follow:A complex-dtype DataArray is accepted silently. Inside
_contours_numpy,np.asarray(data, dtype=np.float64)casts the complex array to float64 and drops the imaginary part, emitting only aComplexWarning. The function then returns contour lines traced on the real part instead of rejecting the input._validate_raster()already rejects complex dtypes.A non-DataArray input (e.g. a plain numpy array) fails late with a confusing error. Instead of a clear "must be an xarray.DataArray" message, it reaches
ArrayTypeFunctionMappingand raisesTypeError: Unsupported Array Type.Expected behavior
contours()should validate its input up front: aValueErrorfor complex/non-numeric dtypes and aTypeErrorfor non-DataArray inputs, matching the rest of the codebase.Additional context
Found during a security sweep (dtype confusion). The fix is to call
_validate_raster(agg, func_name='contours', name='agg', ndim=2)at the top ofcontours(). The silent complex-dtype path is the higher-severity half: it produces wrong results with no error.