Repository: rasterio/rasterio

Issue:
Unavoidable DeprecationWarning on boundless keyword in windows.py
I'm completely lost on proper usage from changes within the new PR for window specification (#1074).  Here's a small sample:
```
>>> with rasterio.open('./tests/data/RGB.byte.tif') as src:
...   w = src.window(*src.bounds)
...
C:\Users\gregorma\Envs\default\lib\site-packages\rasterio\windows.py:205: RasterioDeprecationWarning: boundless keyword should not be used
  RasterioDeprecationWarning)
>>> w
Window(col_off=2.6663542485039216e-09, row_off=2.6648194761946797e-09, width=791.0, height=718.0)    
```
It looks like there is currently no way around getting the `DeprecationWarning` since the `boundless` keyword is getting set [here](https://github.com/mapbox/rasterio/blob/522cf4d7f45b9bf3a1d9ca2f42e6b9f417cd4e8e/rasterio/io.py#L134-L137) from the calling method.  I read through the PR trying to find reference on proper usage, but may have missed it.  I'm likely doing something dumb.


Discussion:
I'm pretty sure it's I who messed up. I'll check into this today.

Resolving patch:
diff --git a/rasterio/io.py b/rasterio/io.py
--- a/rasterio/io.py
+++ b/rasterio/io.py
@@ -16,6 +16,7 @@
 from rasterio import windows
 from rasterio.enums import Resampling
 from rasterio.env import ensure_env
+from rasterio.errors import RasterioDeprecationWarning
 from rasterio.transform import guard_transform, xy, rowcol
 
 
@@ -105,36 +106,40 @@ class WindowMethodsMixin(object):
     properties: `transform`, `height` and `width`
     """
 
-    def window(self, left, bottom, right, top, boundless=True, precision=6):
+    def window(self, left, bottom, right, top, precision=6, **kwargs):
         """Get the window corresponding to the bounding coordinates.
 
+        The resulting window is not cropped to the row and column
+        limits of the dataset.
+
         Parameters
         ----------
-        left : float
+        left: float
             Left (west) bounding coordinate
-        bottom : float
+        bottom: float
             Bottom (south) bounding coordinate
-        right : float
+        right: float
             Right (east) bounding coordinate
-        top : float
+        top: float
             Top (north) bounding coordinate
-        boundless: boolean, optional
-            If boundless is False, window is limited
-            to extent of this dataset.
-        precision : int, optional
+        precision: int, optional
             Number of decimal points of precision when computing inverse
             transform.
+        kwargs: mapping
+            For backwards compatibility: absorbs deprecated keyword args.
 
         Returns
         -------
         window: Window
         """
+        if 'boundless' in kwargs:  # pragma: no branch
+            warnings.warn("boundless keyword arg should not be used",
+                          RasterioDeprecationWarning)
 
         transform = guard_transform(self.transform)
         return windows.from_bounds(
             left, bottom, right, top, transform=transform,
-            height=self.height, width=self.width, boundless=boundless,
-            precision=precision)
+            height=self.height, width=self.width, precision=precision)
 
     def window_transform(self, window):
         """Get the affine transform for a dataset window.
diff --git a/rasterio/merge.py b/rasterio/merge.py
--- a/rasterio/merge.py
+++ b/rasterio/merge.py
@@ -141,16 +141,14 @@ def merge(sources, bounds=None, res=None, nodata=None, precision=7):
 
         # 2. Compute the source window.
         src_window = windows.from_bounds(
-            int_w, int_s, int_e, int_n, src.transform,
-            boundless=True)
+            int_w, int_s, int_e, int_n, src.transform)
         logger.debug("Src %s window: %r", src.name, src_window)
 
         src_window = src_window.round_shape()
 
         # 3. Compute the destination window.
         dst_window = windows.from_bounds(
-            int_w, int_s, int_e, int_n, output_transform,
-            boundless=True)
+            int_w, int_s, int_e, int_n, output_transform)
 
         # 4. Initialize temp array.
         tcount = first.count
@@ -170,6 +168,7 @@ def merge(sources, bounds=None, res=None, nodata=None, precision=7):
 
         np.copyto(
             region, temp,
-            where=np.logical_and(region == nodataval, temp.mask == False))
+            where=np.logical_and(region == nodataval,
+                                 np.logical_not(temp.mask)))
 
     return dest, output_transform
diff --git a/rasterio/windows.py b/rasterio/windows.py
--- a/rasterio/windows.py
+++ b/rasterio/windows.py
@@ -184,16 +184,18 @@ def from_bounds(left, bottom, right, top, transform=None,
 
     Parameters
     ----------
-    left, bottom, right, top : float
+    left, bottom, right, top: float
         Left (west), bottom (south), right (east), and top (north)
         bounding coordinates.
-    transform : Affine
+    transform: Affine
         Affine transform matrix.
-    height, width : int
+    height, width: int
         Number of rows and columns of the window.
-    precision : int, optional
+    precision: int, optional
         Number of decimal points of precision when computing inverse
         transform.
+    kwargs: mapping
+        Absorbs deprecated keyword args
 
     Returns
     -------
@@ -476,7 +478,8 @@ def toslices(self):
 
     @property
     def num_cols(self):
-        warnings.warn("use 'width' attribute instead", RasterioDeprecationWarning)
+        warnings.warn("use 'width' attribute instead",
+                      RasterioDeprecationWarning)
         return self.width
 
     @property


Test patch:
diff --git a/tests/test_blocks.py b/tests/test_blocks.py
--- a/tests/test_blocks.py
+++ b/tests/test_blocks.py
@@ -156,8 +156,7 @@ def test_block_windows_filtered_none(path_rgb_byte_tif):
     """Get no block windows using filter"""
     with rasterio.open(path_rgb_byte_tif) as src:
         w, s, e, n = src.bounds
-        focus_window = src.window(w - 100.0, n + 1.0, w - 1.0, n + 100.0,
-                                  boundless=True)
+        focus_window = src.window(w - 100.0, n + 1.0, w - 1.0, n + 100.0)
         filter_func = partial(windows.intersect, focus_window)
         itr = ((ij, win) for ij, win in src.block_windows() if filter_func(win))
         with pytest.raises(StopIteration):
diff --git a/tests/test_indexing.py b/tests/test_indexing.py
--- a/tests/test_indexing.py
+++ b/tests/test_indexing.py
@@ -41,7 +41,7 @@ def test_window_no_exception():
         left, bottom, right, top = src.bounds
         left -= 1000.0
         assert_window_almost_equals(
-            src.window(left, bottom, right, top, boundless=True),
+            src.window(left, bottom, right, top),
             ((0, src.height), (-1000 / src.res[0], src.width)))
 
 
diff --git a/tests/test_io_mixins.py b/tests/test_io_mixins.py
--- a/tests/test_io_mixins.py
+++ b/tests/test_io_mixins.py
@@ -2,6 +2,7 @@
 import pytest
 
 import rasterio
+from rasterio.errors import RasterioDeprecationWarning
 from rasterio.io import WindowMethodsMixin
 from rasterio.windows import Window
 
@@ -99,3 +100,9 @@ def test_window_bounds_function():
         rows = src.height
         cols = src.width
         assert src.window_bounds(((0, rows), (0, cols))) == src.bounds
+
+
+def test_boundless_deprecation():
+    with pytest.warns(RasterioDeprecationWarning):
+        with rasterio.open('tests/data/RGB.byte.tif') as src:
+            src.window(*src.bounds, boundless=True)
diff --git a/tests/test_vfs.py b/tests/test_vfs.py
--- a/tests/test_vfs.py
+++ b/tests/test_vfs.py
@@ -88,8 +88,7 @@ def test_read_vfs_none():
 @pytest.mark.parametrize('mode', ['r+', 'w'])
 def test_update_vfs(tmpdir, mode):
     """VFS datasets can not be created or updated"""
+    profile = default_gtiff_profile.copy()
+    profile.update(count=1, width=1, height=1)
     with pytest.raises(TypeError):
-        rasterio.open(
-            'zip://{0}'.format(tmpdir), mode,
-            **default_gtiff_profile(
-                count=1, width=1, height=1))
+        rasterio.open('zip://{0}'.format(tmpdir), mode, **profile)