diff --git a/docs/history.rst b/docs/history.rst index 7c7da30c..7819e42e 100644 --- a/docs/history.rst +++ b/docs/history.rst @@ -3,6 +3,7 @@ History Latest ------ +- BUG: Raise OverflowError when nodata data type conversion is unsafe (pull #782) 0.15.5 ------ diff --git a/rioxarray/raster_writer.py b/rioxarray/raster_writer.py index 5f1f8f0d..cc573ad9 100644 --- a/rioxarray/raster_writer.py +++ b/rioxarray/raster_writer.py @@ -8,8 +8,6 @@ - https://github.com/dymaxionlabs/dask-rasterio/blob/8dd7fdece7ad094a41908c0ae6b4fe6ca49cf5e1/dask_rasterio/write.py # noqa: E501 """ -import warnings - import numpy import rasterio from rasterio.windows import Window @@ -121,17 +119,21 @@ def _ensure_nodata_dtype(original_nodata, new_dtype): if the value of the nodata value changed. """ # Complex-valued rasters can have real-valued nodata - if str(new_dtype).startswith("c"): + new_dtype = numpy.dtype(new_dtype) + if numpy.issubdtype(new_dtype, numpy.complexfloating): nodata = original_nodata else: original_nodata = float(original_nodata) - nodata = numpy.dtype(new_dtype).type(original_nodata) + failure_message = ( + f"Unable to convert nodata value ({original_nodata}) to " + f"new dtype ({new_dtype})." + ) + try: + nodata = new_dtype.type(original_nodata) + except OverflowError as error: + raise OverflowError(failure_message) from error if not numpy.isnan(nodata) and original_nodata != nodata: - warnings.warn( - f"The nodata value ({original_nodata}) has been automatically " - f"changed to ({nodata}) to match the dtype of the data." - ) - + raise OverflowError(failure_message) return nodata diff --git a/test/integration/test_integration_rioxarray.py b/test/integration/test_integration_rioxarray.py index b97bb64b..fdb3f6bf 100644 --- a/test/integration/test_integration_rioxarray.py +++ b/test/integration/test_integration_rioxarray.py @@ -1886,19 +1886,9 @@ def test_to_raster__different_dtype(tmp_path, windowed): ) test_nd.rio.write_crs("EPSG:4326", inplace=True) tmpfile = tmp_path / "dtype.tif" - with pytest.warns( - UserWarning, - match=( - r"The nodata value \(-1.1\) has been automatically changed to " - r"\(255\) to match the dtype of the data." - ), - ): + + with pytest.raises(OverflowError, match="Unable to convert nodata value"): test_nd.rio.to_raster(tmpfile, dtype=numpy.uint8, windowed=windowed) - with rioxarray.open_rasterio(tmpfile) as xds: - assert str(xds.dtype) == "uint8" - assert xds.attrs["_FillValue"] == 255 - assert xds.rio.nodata == 255 - assert xds.squeeze().values[1, 1] == 255 def test_missing_spatial_dimensions(): @@ -2384,17 +2374,8 @@ def test_write_nodata__different_dtype(nodata): dims=("y", "x"), coords={"y": numpy.arange(1, 6), "x": numpy.arange(2, 7)}, ) - with pytest.warns( - UserWarning, - match=( - r"The nodata value \(-1.1\) has been automatically changed to " - r"\(-1\) to match the dtype of the data." - ), - ): - test_nd = test_da.rio.write_nodata(nodata) - assert not test_da.attrs - assert test_nd.attrs["_FillValue"] == -1 - assert test_nd.rio.nodata == -1 + with pytest.raises(OverflowError, match="Unable to convert nodata value"): + test_da.rio.write_nodata(nodata) @pytest.mark.parametrize("nodata", [-1.1, "-1.1"]) @@ -2406,14 +2387,8 @@ def test_nodata_reader__different_dtype(nodata): attrs={"_FillValue": nodata}, ) assert test_da.attrs["_FillValue"] == nodata - with pytest.warns( - UserWarning, - match=( - r"The nodata value \(-1.1\) has been automatically changed to " - r"\(255\) to match the dtype of the data." - ), - ): - assert test_da.rio.nodata == 255 + with pytest.raises(OverflowError, match="Unable to convert nodata value"): + test_da.rio.nodata def test_isel_window():