Repository: rasterio/rasterio

Issue:
Turn down logging level for non-existing files in the Python file VSI plugin
To prevent pointless sidecar searching as discussed in https://github.com/rasterio/rasterio/discussions/2825.


Discussion:

Resolving patch:
diff --git a/rasterio/io.py b/rasterio/io.py
--- a/rasterio/io.py
+++ b/rasterio/io.py
@@ -13,7 +13,7 @@
     MemoryFileBase,
 )
 from rasterio.windows import WindowMethodsMixin
-from rasterio.env import ensure_env
+from rasterio.env import Env, ensure_env
 from rasterio.transform import TransformMethodsMixin
 from rasterio._path import _UnparsedPath
 
@@ -214,13 +214,25 @@ def open(self, driver=None, sharing=False, **kwargs):
 
         Parameters are optional and have the same semantics as the
         parameters of `rasterio.open()`.
+
+        Returns
+        -------
+        DatasetReader
+
+        Raises
+        ------
+        IOError
+            If the memory file is closed.
+
         """
         mempath = _UnparsedPath(self.name)
 
         if self.closed:
             raise IOError("I/O operation on closed file.")
+
         # Assume we were given a non-empty file-like object
         log.debug("VSI path: {}".format(mempath.path))
+
         return DatasetReader(mempath, driver=driver, sharing=sharing, **kwargs)
 
     def __enter__(self):


Test patch:
diff --git a/tests/test_filepath.py b/tests/test_filepath.py
--- a/tests/test_filepath.py
+++ b/tests/test_filepath.py
@@ -2,6 +2,7 @@
 Tests in this file will ONLY run for GDAL >= 3.x"""
 
 from io import BytesIO
+import logging
 import os.path
 
 import pytest
@@ -139,9 +140,12 @@ def test_vsifile_copyfiles(path_rgb_msk_byte_tif):
 @pytest.mark.xfail(reason="FilePath does not implement '.files' property properly.")
 def test_multi_vsifile(path_rgb_msk_byte_tif):
     """Multiple files can be copied to a FilePath using copyfiles"""
-    with open(path_rgb_msk_byte_tif, 'rb') as tif_fp, open(path_rgb_msk_byte_tif + '.msk', 'rb') as msk_fp:
-        with FilePath(tif_fp, dirname="bar", filename='foo.tif') as tifvsifile, \
-                FilePath(msk_fp, dirname="bar", filename='foo.tif.msk') as mskvsifile:
+    with open(path_rgb_msk_byte_tif, "rb") as tif_fp, open(
+        path_rgb_msk_byte_tif + ".msk", "rb"
+    ) as msk_fp:
+        with FilePath(
+            tif_fp, dirname="bar", filename="foo.tif"
+        ) as tifvsifile, FilePath(msk_fp, dirname="bar", filename="foo.tif.msk"):
             with tifvsifile.open() as src:
                 assert sorted(os.path.basename(fn) for fn in src.files) == sorted(['foo.tif', 'foo.tif.msk'])
                 assert src.mask_flag_enums == ([MaskFlags.per_dataset],) * 3
@@ -182,3 +186,13 @@ def test_python_file_reuse():
 
     with rasterio.open(ascii_raster_io) as rds:
         _ = rds.bounds
+
+
+def test_quieter_vsi_plugin_notifications(caplog, path_rgb_byte_tif):
+    """Expect no warning or error level log messages about .aux or .hdr files."""
+    with caplog.at_level(logging.WARNING):
+        with open(path_rgb_byte_tif, "rb") as f, FilePath(f) as vsi_file:
+            with vsi_file.open() as src:
+                _ = src.profile
+
+        assert "not found in virtual filesystem" not in caplog.text
diff --git a/tests/test_memoryfile.py b/tests/test_memoryfile.py
--- a/tests/test_memoryfile.py
+++ b/tests/test_memoryfile.py
@@ -342,7 +342,9 @@ def test_multi_memfile(path_rgb_msk_byte_tif):
     with open(path_rgb_msk_byte_tif + '.msk', 'rb') as msk_fp:
         msk_bytes = msk_fp.read()
 
-    with MemoryFile(tif_bytes, dirname="bar", filename='foo.tif') as tifmemfile, MemoryFile(msk_bytes, dirname="bar", filename='foo.tif.msk') as mskmemfile:
+    with MemoryFile(
+        tif_bytes, dirname="bar", filename="foo.tif"
+    ) as tifmemfile, MemoryFile(msk_bytes, dirname="bar", filename="foo.tif.msk"):
         with tifmemfile.open() as src:
             assert sorted(os.path.basename(fn) for fn in src.files) == sorted(['foo.tif', 'foo.tif.msk'])
             assert src.mask_flag_enums == ([MaskFlags.per_dataset],) * 3
@@ -387,3 +389,4 @@ def test_write_rpcs_to_memfile(path_rgb_byte_rpc_vrt):
                 assert dst.rpcs is None
                 dst.rpcs = src.rpcs
                 assert dst.rpcs
+
diff --git a/tests/test_warp.py b/tests/test_warp.py
--- a/tests/test_warp.py
+++ b/tests/test_warp.py
@@ -289,6 +289,7 @@ def test_transform_bounds__esri_wkt():
     )
 
 
+@pytest.mark.xfail(reason="Projection extents have changed with PROJ 9")
 @pytest.mark.parametrize(
     "density,expected",
     [