Repository: rasterio/rasterio

Issue:
Cast nodata value before filling in rio calc
At line 192, `res = res.filled(kwargs['nodata'])`, we need to convert that string to a numpy scalar or array of `res` dtype.


Discussion:

Resolving patch:
diff --git a/rasterio/rio/calc.py b/rasterio/rio/calc.py
--- a/rasterio/rio/calc.py
+++ b/rasterio/rio/calc.py
@@ -185,17 +185,14 @@ def calc(ctx, command, files, output, driver, name, dtype, masked, overwrite, me
                     ctxkwds[name or '_i%d' % (i + 1)] = src.read(masked=masked, window=window)
 
                 res = snuggs.eval(command, **ctxkwds)
-
-                if (isinstance(res, np.ma.core.MaskedArray) and (
-                        tuple(LooseVersion(np.__version__).version) < (1, 9) or
-                        tuple(LooseVersion(np.__version__).version) > (1, 10))):
-                    res = res.filled(kwargs['nodata'])
-
-                if len(res.shape) == 3:
-                    results = np.ndarray.astype(res, dtype, copy=False)
-                else:
-                    results = np.asanyarray(
-                        [np.ndarray.astype(res, dtype, copy=False)])
+                results = res.astype(dtype, copy=False)
+
+                if isinstance(results, np.ma.core.MaskedArray):
+                    results = results.filled(float(kwargs['nodata']))
+                    if len(results.shape) == 2:
+                        results = np.ma.asanyarray([results])
+                elif len(results.shape) == 2:
+                    results = np.asanyarray([results])
 
                 # The first iteration is only to get sample results and from them
                 # compute some properties of the output dataset.


Test patch:
diff --git a/tests/test_rio_calc.py b/tests/test_rio_calc.py
--- a/tests/test_rio_calc.py
+++ b/tests/test_rio_calc.py
@@ -180,3 +180,26 @@ def test_chunk_output(width, height, count, itemsize, mem_limit):
     num_windows_cols = max([j for ((i, j), w) in work_windows]) + 1
     assert sum((w.width for ij, w in work_windows)) == width * num_windows_rows
     assert sum((w.height for ij, w in work_windows)) == height * num_windows_cols
+
+
+def test_bool(tmpdir, runner):
+    """Check on issue #2401"""
+    outfile = str(tmpdir.join("out.tif"))
+    result = runner.invoke(
+        main_group,
+        ["calc"]
+        + [
+            "(>= (read 1 1) 127)",
+            "-t",
+            "uint8",
+            "--masked",
+            "--profile",
+            "nodata=255",
+            "tests/data/RGB.byte.tif",
+            outfile,
+        ],
+        catch_exceptions=False,
+    )
+    assert result.exit_code == 0
+    with rasterio.open(outfile) as src:
+        assert (src.read() == 255).any()
diff --git a/tests/test_rio_merge.py b/tests/test_rio_merge.py
--- a/tests/test_rio_merge.py
+++ b/tests/test_rio_merge.py
@@ -146,9 +146,11 @@ def test_merge_error(test_data_dir_1, runner):
     outputname = str(test_data_dir_1.join('merged.tif'))
     inputs = [str(x) for x in test_data_dir_1.listdir()]
     inputs.sort()
-    result = runner.invoke(
-        main_group, ['merge'] + inputs + [outputname] + ['--nodata', '-1'])
-    assert result.exit_code
+    with pytest.warns(UserWarning):
+        result = runner.invoke(
+            main_group, ["merge"] + inputs + [outputname] + ["--nodata", "-1"]
+        )
+        assert result.exit_code
 
 
 def test_merge_bidx(test_data_dir_3, runner):