prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <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 
  
  
  </issue>
  <code>
  [start of rasterio/rio/merge.py]
  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 of rasterio/rio/merge.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: 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()
  
verification_info: {"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"}]}