We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
rio merge assumes nodata
Running `rio merge` over a set of images without a nodata value results in an error:

```
(rio-test)$ rio merge warped.tif merged.tif
ERROR:rio:Failed. Exception caught
Traceback (most recent call last):
  File "/Users/amit/Mapbox/rasterio/rasterio/rio/merge.py", line 50, in merge
    dest.fill(nodataval)
TypeError: long() argument must be a string or a number, not 'NoneType'
```

Checking for nodata in `rasterio/rio/merge.py` still results in a lower level error (https://github.com/mapbox/rasterio/commit/6b251f8261fd1b3e785dc73462212741b6bd62b7):

```
(rio-test)$ rio merge warped.tif merged.tif
ERROR:rio:Failed. Exception caught
Traceback (most recent call last):
  File "/Users/amit/Mapbox/rasterio/rasterio/rio/merge.py", line 55, in merge
    data = src.read()
  File "rasterio/_io.pyx", line 654, in rasterio._io.RasterReader.read (rasterio/_io.c:8075)
    arr.fill(ndv)
TypeError: long() argument must be a string or a number, not 'NoneType'
```

Patching this case throws the error down further until a regular numpy array is confused for a masked array (https://github.com/mapbox/rasterio/commit/c271c4ee23531db7c24208c85f56d04d79acc851):

```
(rio-test)$ rio merge warped.tif merged.tif
/Users/amit/Mapbox/rasterio/rasterio/rio/merge.py:58: FutureWarning: comparison to `None` will result in an elementwise object comparison in the future.
  dest==nodataval, data.mask==False))
ERROR:rio:Failed. Exception caught
Traceback (most recent call last):
  File "/Users/amit/Mapbox/rasterio/rasterio/rio/merge.py", line 58, in merge
    dest==nodataval, data.mask==False))
AttributeError: 'numpy.ndarray' object has no attribute 'mask'
```

/cc @sgillies 


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `rasterio/rio/merge.py`
Content:
```
1 # Merge command.
2 
3 import logging
4 import os.path
5 import sys
6 
7 import click
8 from cligj import files_inout_arg, format_opt
9 
10 import rasterio
11 
12 from rasterio.rio.cli import cli
13 
14 
15 @cli.command(short_help="Merge a stack of raster datasets.")
16 @files_inout_arg
17 @format_opt
18 @click.pass_context
19 def merge(ctx, files, driver):
20     """Copy valid pixels from input files to an output file.
21 
22     All files must have the same shape, number of bands, and data type.
23 
24     Input files are merged in their listed order using a reverse
25     painter's algorithm.
26     """
27     import numpy as np
28 
29     verbosity = (ctx.obj and ctx.obj.get('verbosity')) or 1
30     logger = logging.getLogger('rio')
31     try:
32         with rasterio.drivers(CPL_DEBUG=verbosity>2):
33             output = files[-1]
34             files = files[:-1]
35 
36             with rasterio.open(files[0]) as first:
37                 kwargs = first.meta
38                 kwargs['transform'] = kwargs.pop('affine')
39                 dest = np.empty((first.count,) + first.shape, 
40                     dtype=first.dtypes[0])
41 
42             if os.path.exists(output):
43                 dst = rasterio.open(output, 'r+')
44                 nodataval = dst.nodatavals[0]
45             else:
46                 kwargs['driver'] == driver
47                 dst = rasterio.open(output, 'w', **kwargs)
48                 nodataval = first.nodatavals[0]
49 
50             dest.fill(nodataval)
51 
52             for fname in reversed(files):
53                 with rasterio.open(fname) as src:
54                     data = src.read()
55                     np.copyto(dest, data,
56                         where=np.logical_and(
57                         dest==nodataval, data.mask==False))
58 
59             if dst.mode == 'r+':
60                 data = dst.read()
61                 np.copyto(dest, data,
62                     where=np.logical_and(
63                     dest==nodataval, data.mask==False))
64 
65             dst.write(dest)
66             dst.close()
67 
68         sys.exit(0)
69     except Exception:
70         logger.exception("Failed. Exception caught")
71         sys.exit(1)
72
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/rasterio/rio/merge.py b/rasterio/rio/merge.py
--- a/rasterio/rio/merge.py
+++ b/rasterio/rio/merge.py
@@ -36,31 +36,39 @@
             with rasterio.open(files[0]) as first:
                 kwargs = first.meta
                 kwargs['transform'] = kwargs.pop('affine')
-                dest = np.empty((first.count,) + first.shape, 
+                dest = np.zeros((first.count,) + first.shape, 
                     dtype=first.dtypes[0])
 
+            nodataval = next(dest.flat)
             if os.path.exists(output):
                 dst = rasterio.open(output, 'r+')
-                nodataval = dst.nodatavals[0]
+                nodataval = dst.nodatavals[0] or nodataval
             else:
                 kwargs['driver'] == driver
                 dst = rasterio.open(output, 'w', **kwargs)
-                nodataval = first.nodatavals[0]
+                nodataval = first.nodatavals[0] or nodataval
 
-            dest.fill(nodataval)
+            if nodataval:
+                dest.fill(nodataval)
 
             for fname in reversed(files):
                 with rasterio.open(fname) as src:
                     data = src.read()
-                    np.copyto(dest, data,
-                        where=np.logical_and(
-                        dest==nodataval, data.mask==False))
+                    try:
+                        where = np.logical_and(
+                                dest==nodataval, data.mask==False)
+                    except AttributeError:
+                        where = dest==nodataval
+                    np.copyto(dest, data, where=where)
 
             if dst.mode == 'r+':
                 data = dst.read()
-                np.copyto(dest, data,
-                    where=np.logical_and(
-                    dest==nodataval, data.mask==False))
+                try:
+                    where = np.logical_and(
+                            dest==nodataval, data.mask==False)
+                except AttributeError:
+                    where = dest==nodataval
+                np.copyto(dest, data, where=where)
 
             dst.write(dest)
             dst.close()

{"golden_diff": "diff --git a/rasterio/rio/merge.py b/rasterio/rio/merge.py\n--- a/rasterio/rio/merge.py\n+++ b/rasterio/rio/merge.py\n@@ -36,31 +36,39 @@\n             with rasterio.open(files[0]) as first:\n                 kwargs = first.meta\n                 kwargs['transform'] = kwargs.pop('affine')\n-                dest = np.empty((first.count,) + first.shape, \n+                dest = np.zeros((first.count,) + first.shape, \n                     dtype=first.dtypes[0])\n \n+            nodataval = next(dest.flat)\n             if os.path.exists(output):\n                 dst = rasterio.open(output, 'r+')\n-                nodataval = dst.nodatavals[0]\n+                nodataval = dst.nodatavals[0] or nodataval\n             else:\n                 kwargs['driver'] == driver\n                 dst = rasterio.open(output, 'w', **kwargs)\n-                nodataval = first.nodatavals[0]\n+                nodataval = first.nodatavals[0] or nodataval\n \n-            dest.fill(nodataval)\n+            if nodataval:\n+                dest.fill(nodataval)\n \n             for fname in reversed(files):\n                 with rasterio.open(fname) as src:\n                     data = src.read()\n-                    np.copyto(dest, data,\n-                        where=np.logical_and(\n-                        dest==nodataval, data.mask==False))\n+                    try:\n+                        where = np.logical_and(\n+                                dest==nodataval, data.mask==False)\n+                    except AttributeError:\n+                        where = dest==nodataval\n+                    np.copyto(dest, data, where=where)\n \n             if dst.mode == 'r+':\n                 data = dst.read()\n-                np.copyto(dest, data,\n-                    where=np.logical_and(\n-                    dest==nodataval, data.mask==False))\n+                try:\n+                    where = np.logical_and(\n+                            dest==nodataval, data.mask==False)\n+                except AttributeError:\n+                    where = dest==nodataval\n+                np.copyto(dest, data, where=where)\n \n             dst.write(dest)\n             dst.close()\n", "issue": "rio merge assumes nodata\nRunning `rio merge` over a set of images without a nodata value results in an error:\n\n```\n(rio-test)$ rio merge warped.tif merged.tif\nERROR:rio:Failed. Exception caught\nTraceback (most recent call last):\n  File \"/Users/amit/Mapbox/rasterio/rasterio/rio/merge.py\", line 50, in merge\n    dest.fill(nodataval)\nTypeError: long() argument must be a string or a number, not 'NoneType'\n```\n\nChecking for nodata in `rasterio/rio/merge.py` still results in a lower level error (https://github.com/mapbox/rasterio/commit/6b251f8261fd1b3e785dc73462212741b6bd62b7):\n\n```\n(rio-test)$ rio merge warped.tif merged.tif\nERROR:rio:Failed. Exception caught\nTraceback (most recent call last):\n  File \"/Users/amit/Mapbox/rasterio/rasterio/rio/merge.py\", line 55, in merge\n    data = src.read()\n  File \"rasterio/_io.pyx\", line 654, in rasterio._io.RasterReader.read (rasterio/_io.c:8075)\n    arr.fill(ndv)\nTypeError: long() argument must be a string or a number, not 'NoneType'\n```\n\nPatching this case throws the error down further until a regular numpy array is confused for a masked array (https://github.com/mapbox/rasterio/commit/c271c4ee23531db7c24208c85f56d04d79acc851):\n\n```\n(rio-test)$ rio merge warped.tif merged.tif\n/Users/amit/Mapbox/rasterio/rasterio/rio/merge.py:58: FutureWarning: comparison to `None` will result in an elementwise object comparison in the future.\n  dest==nodataval, data.mask==False))\nERROR:rio:Failed. Exception caught\nTraceback (most recent call last):\n  File \"/Users/amit/Mapbox/rasterio/rasterio/rio/merge.py\", line 58, in merge\n    dest==nodataval, data.mask==False))\nAttributeError: 'numpy.ndarray' object has no attribute 'mask'\n```\n\n/cc @sgillies \n\n", "before_files": [{"content": "# Merge command.\n\nimport logging\nimport os.path\nimport sys\n\nimport click\nfrom cligj import files_inout_arg, format_opt\n\nimport rasterio\n\nfrom rasterio.rio.cli import cli\n\n\n@cli.command(short_help=\"Merge a stack of raster datasets.\")\n@files_inout_arg\n@format_opt\n@click.pass_context\ndef merge(ctx, files, driver):\n    \"\"\"Copy valid pixels from input files to an output file.\n\n    All files must have the same shape, number of bands, and data type.\n\n    Input files are merged in their listed order using a reverse\n    painter's algorithm.\n    \"\"\"\n    import numpy as np\n\n    verbosity = (ctx.obj and ctx.obj.get('verbosity')) or 1\n    logger = logging.getLogger('rio')\n    try:\n        with rasterio.drivers(CPL_DEBUG=verbosity>2):\n            output = files[-1]\n            files = files[:-1]\n\n            with rasterio.open(files[0]) as first:\n                kwargs = first.meta\n                kwargs['transform'] = kwargs.pop('affine')\n                dest = np.empty((first.count,) + first.shape, \n                    dtype=first.dtypes[0])\n\n            if os.path.exists(output):\n                dst = rasterio.open(output, 'r+')\n                nodataval = dst.nodatavals[0]\n            else:\n                kwargs['driver'] == driver\n                dst = rasterio.open(output, 'w', **kwargs)\n                nodataval = first.nodatavals[0]\n\n            dest.fill(nodataval)\n\n            for fname in reversed(files):\n                with rasterio.open(fname) as src:\n                    data = src.read()\n                    np.copyto(dest, data,\n                        where=np.logical_and(\n                        dest==nodataval, data.mask==False))\n\n            if dst.mode == 'r+':\n                data = dst.read()\n                np.copyto(dest, data,\n                    where=np.logical_and(\n                    dest==nodataval, data.mask==False))\n\n            dst.write(dest)\n            dst.close()\n\n        sys.exit(0)\n    except Exception:\n        logger.exception(\"Failed. Exception caught\")\n        sys.exit(1)\n", "path": "rasterio/rio/merge.py"}], "after_files": [{"content": "# Merge command.\n\nimport logging\nimport os.path\nimport sys\n\nimport click\nfrom cligj import files_inout_arg, format_opt\n\nimport rasterio\n\nfrom rasterio.rio.cli import cli\n\n\n@cli.command(short_help=\"Merge a stack of raster datasets.\")\n@files_inout_arg\n@format_opt\n@click.pass_context\ndef merge(ctx, files, driver):\n    \"\"\"Copy valid pixels from input files to an output file.\n\n    All files must have the same shape, number of bands, and data type.\n\n    Input files are merged in their listed order using a reverse\n    painter's algorithm.\n    \"\"\"\n    import numpy as np\n\n    verbosity = (ctx.obj and ctx.obj.get('verbosity')) or 1\n    logger = logging.getLogger('rio')\n    try:\n        with rasterio.drivers(CPL_DEBUG=verbosity>2):\n            output = files[-1]\n            files = files[:-1]\n\n            with rasterio.open(files[0]) as first:\n                kwargs = first.meta\n                kwargs['transform'] = kwargs.pop('affine')\n                dest = np.zeros((first.count,) + first.shape, \n                    dtype=first.dtypes[0])\n\n            nodataval = next(dest.flat)\n            if os.path.exists(output):\n                dst = rasterio.open(output, 'r+')\n                nodataval = dst.nodatavals[0] or nodataval\n            else:\n                kwargs['driver'] == driver\n                dst = rasterio.open(output, 'w', **kwargs)\n                nodataval = first.nodatavals[0] or nodataval\n\n            if nodataval:\n                dest.fill(nodataval)\n\n            for fname in reversed(files):\n                with rasterio.open(fname) as src:\n                    data = src.read()\n                    try:\n                        where = np.logical_and(\n                                dest==nodataval, data.mask==False)\n                    except AttributeError:\n                        where = dest==nodataval\n                    np.copyto(dest, data, where=where)\n\n            if dst.mode == 'r+':\n                data = dst.read()\n                try:\n                    where = np.logical_and(\n                            dest==nodataval, data.mask==False)\n                except AttributeError:\n                    where = dest==nodataval\n                np.copyto(dest, data, where=where)\n\n            dst.write(dest)\n            dst.close()\n\n        sys.exit(0)\n    except Exception:\n        logger.exception(\"Failed. Exception caught\")\n        sys.exit(1)\n", "path": "rasterio/rio/merge.py"}]}