prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  WarpedVRT does not permit boundless reads (sample.py)
  ## Expected behavior and actual behavior.
  
  ```
      def test_rasterio_vrt(self):
  
          import rasterio
  
      
  
          # tmp_file default crs is UTM: CRS({'init': 'epsg:32618'}
  
          with create_tmp_geotiff() as (tmp_file, expected):
  
              with rasterio.open(tmp_file) as src:
  
                  with rasterio.vrt.WarpedVRT(src, crs="epsg:4326") as vrt:
  
                      expected_shape = (vrt.width, vrt.height)
  
                      expected_crs = vrt.crs
  
                      expected_res = vrt.res
  
                      # Value of single pixel in center of image
  
                      lon, lat = vrt.xy(vrt.width // 2, vrt.height // 2)
  
  >                   expected_val = next(vrt.sample([(lon, lat)]))
  
  test/integration/test_integration__io.py:799: 
  
  _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
  
  ../../../miniconda/envs/test/lib/python3.7/site-packages/rasterio/sample.py:43: in sample_gen
  
      data = read(indexes, window=window, masked=masked, boundless=True)
  
  _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
  
  >   ???
  
  E   ValueError: WarpedVRT does not permit boundless reads
  ```
  
  ## Operating system
  
  For example: Mac OS, Windows, Linux
  
  ## Rasterio version and provenance
  
  1.1.1 from conda-forge
  
  </issue>
  <code>
  [start of rasterio/sample.py]
  1 # Workaround for issue #378. A pure Python generator.
  2 
  3 import numpy
  4 
  5 from rasterio.windows import Window
  6 
  7 
  8 def sample_gen(dataset, xy, indexes=None, masked=False):
  9     """Sample pixels from a dataset
  10 
  11     Parameters
  12     ----------
  13     dataset : rasterio Dataset
  14         Opened in "r" mode.
  15     xy : iterable
  16         Pairs of x, y coordinates in the dataset's reference system.
  17     indexes : int or list of int
  18         Indexes of dataset bands to sample.
  19     masked : bool, default: False
  20         Whether to mask samples that fall outside the extent of the
  21         dataset.
  22 
  23     Yields
  24     ------
  25     array
  26         A array of length equal to the number of specified indexes
  27         containing the dataset values for the bands corresponding to
  28         those indexes.
  29 
  30     """
  31     index = dataset.index
  32     read = dataset.read
  33 
  34     if isinstance(indexes, int):
  35         indexes = [indexes]
  36 
  37     for x, y in xy:
  38         row_off, col_off = index(x, y)
  39 #        if row_off < 0 or col_off < 0:
  40 #            yield numpy.ones((dataset.count,), dtype=dataset.dtypes[0]) * dataset.nodata
  41 #        else:
  42         window = Window(col_off, row_off, 1, 1)
  43         data = read(indexes, window=window, masked=masked, boundless=True)
  44         yield data[:, 0, 0]
  45
  [end of rasterio/sample.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/sample.py b/rasterio/sample.py
  --- a/rasterio/sample.py
  +++ b/rasterio/sample.py
  @@ -2,6 +2,7 @@
   
   import numpy
   
  +from rasterio.enums import MaskFlags
   from rasterio.windows import Window
   
   
  @@ -31,14 +32,24 @@
       index = dataset.index
       read = dataset.read
   
  -    if isinstance(indexes, int):
  +    if indexes is None:
  +        indexes = dataset.indexes
  +    elif isinstance(indexes, int):
           indexes = [indexes]
   
       for x, y in xy:
  +
           row_off, col_off = index(x, y)
  -#        if row_off < 0 or col_off < 0:
  -#            yield numpy.ones((dataset.count,), dtype=dataset.dtypes[0]) * dataset.nodata
  -#        else:
  -        window = Window(col_off, row_off, 1, 1)
  -        data = read(indexes, window=window, masked=masked, boundless=True)
  -        yield data[:, 0, 0]
  +
  +        if row_off < 0 or col_off < 0 or row_off >= dataset.height or col_off >= dataset.width:
  +            data = numpy.ones((len(indexes),), dtype=dataset.dtypes[0]) * (dataset.nodata or 0)
  +            if masked:
  +                mask = [False if MaskFlags.all_valid in dataset.mask_flag_enums[i - 1] else True for i in indexes]
  +                yield numpy.ma.array(data, mask=mask)
  +            else:
  +                yield data
  +
  +        else:
  +            window = Window(col_off, row_off, 1, 1)
  +            data = read(indexes, window=window, masked=masked)
  +            yield data[:, 0, 0]
  
verification_info: {"golden_diff": "diff --git a/rasterio/sample.py b/rasterio/sample.py\n--- a/rasterio/sample.py\n+++ b/rasterio/sample.py\n@@ -2,6 +2,7 @@\n \n import numpy\n \n+from rasterio.enums import MaskFlags\n from rasterio.windows import Window\n \n \n@@ -31,14 +32,24 @@\n     index = dataset.index\n     read = dataset.read\n \n-    if isinstance(indexes, int):\n+    if indexes is None:\n+        indexes = dataset.indexes\n+    elif isinstance(indexes, int):\n         indexes = [indexes]\n \n     for x, y in xy:\n+\n         row_off, col_off = index(x, y)\n-#        if row_off < 0 or col_off < 0:\n-#            yield numpy.ones((dataset.count,), dtype=dataset.dtypes[0]) * dataset.nodata\n-#        else:\n-        window = Window(col_off, row_off, 1, 1)\n-        data = read(indexes, window=window, masked=masked, boundless=True)\n-        yield data[:, 0, 0]\n+\n+        if row_off < 0 or col_off < 0 or row_off >= dataset.height or col_off >= dataset.width:\n+            data = numpy.ones((len(indexes),), dtype=dataset.dtypes[0]) * (dataset.nodata or 0)\n+            if masked:\n+                mask = [False if MaskFlags.all_valid in dataset.mask_flag_enums[i - 1] else True for i in indexes]\n+                yield numpy.ma.array(data, mask=mask)\n+            else:\n+                yield data\n+\n+        else:\n+            window = Window(col_off, row_off, 1, 1)\n+            data = read(indexes, window=window, masked=masked)\n+            yield data[:, 0, 0]\n", "issue": "WarpedVRT does not permit boundless reads (sample.py)\n## Expected behavior and actual behavior.\r\n\r\n```\r\n    def test_rasterio_vrt(self):\r\n\r\n        import rasterio\r\n\r\n    \r\n\r\n        # tmp_file default crs is UTM: CRS({'init': 'epsg:32618'}\r\n\r\n        with create_tmp_geotiff() as (tmp_file, expected):\r\n\r\n            with rasterio.open(tmp_file) as src:\r\n\r\n                with rasterio.vrt.WarpedVRT(src, crs=\"epsg:4326\") as vrt:\r\n\r\n                    expected_shape = (vrt.width, vrt.height)\r\n\r\n                    expected_crs = vrt.crs\r\n\r\n                    expected_res = vrt.res\r\n\r\n                    # Value of single pixel in center of image\r\n\r\n                    lon, lat = vrt.xy(vrt.width // 2, vrt.height // 2)\r\n\r\n>                   expected_val = next(vrt.sample([(lon, lat)]))\r\n\r\ntest/integration/test_integration__io.py:799: \r\n\r\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \r\n\r\n../../../miniconda/envs/test/lib/python3.7/site-packages/rasterio/sample.py:43: in sample_gen\r\n\r\n    data = read(indexes, window=window, masked=masked, boundless=True)\r\n\r\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \r\n\r\n>   ???\r\n\r\nE   ValueError: WarpedVRT does not permit boundless reads\r\n```\r\n\r\n## Operating system\r\n\r\nFor example: Mac OS, Windows, Linux\r\n\r\n## Rasterio version and provenance\r\n\r\n1.1.1 from conda-forge\n", "before_files": [{"content": "# Workaround for issue #378. A pure Python generator.\n\nimport numpy\n\nfrom rasterio.windows import Window\n\n\ndef sample_gen(dataset, xy, indexes=None, masked=False):\n    \"\"\"Sample pixels from a dataset\n\n    Parameters\n    ----------\n    dataset : rasterio Dataset\n        Opened in \"r\" mode.\n    xy : iterable\n        Pairs of x, y coordinates in the dataset's reference system.\n    indexes : int or list of int\n        Indexes of dataset bands to sample.\n    masked : bool, default: False\n        Whether to mask samples that fall outside the extent of the\n        dataset.\n\n    Yields\n    ------\n    array\n        A array of length equal to the number of specified indexes\n        containing the dataset values for the bands corresponding to\n        those indexes.\n\n    \"\"\"\n    index = dataset.index\n    read = dataset.read\n\n    if isinstance(indexes, int):\n        indexes = [indexes]\n\n    for x, y in xy:\n        row_off, col_off = index(x, y)\n#        if row_off < 0 or col_off < 0:\n#            yield numpy.ones((dataset.count,), dtype=dataset.dtypes[0]) * dataset.nodata\n#        else:\n        window = Window(col_off, row_off, 1, 1)\n        data = read(indexes, window=window, masked=masked, boundless=True)\n        yield data[:, 0, 0]\n", "path": "rasterio/sample.py"}]}