prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  more explicit NotImplementedError messages in read mode ?
  In wanting to set a GeoTIFF's CRS, I encountered [this](https://github.com/mapbox/rasterio/blob/master/rasterio/_base.pyx#L516) NotImplementedError when trying to run the following code:
  ```
  with rasterio.open(filepath) as src:
      src.crs = "EPSG:3857"
  ```
  Though in retrospect it is obvious the above will fail without explicitly specifying the proper  mode , i.e. `'r+'` in this case,  I was momentarily thrown off by the error and assumed something was wrong with my approach. Would a more explicit error message be useful here?
  
  
  --- 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/errors.py`
  Content:
  ```
  1 """Errors and Warnings."""
  2 
  3 from click import FileError
  4 
  5 
  6 class RasterioError(Exception):
  7     """Root exception class"""
  8 
  9 
  10 class WindowError(RasterioError):
  11     """Raised when errors occur during window operations"""
  12 
  13 
  14 class CRSError(ValueError):
  15     """Raised when a CRS string or mapping is invalid or cannot serve
  16     to define a coordinate transformation."""
  17 
  18 
  19 class EnvError(RasterioError):
  20     """Raised when the state of GDAL/AWS environment cannot be created
  21     or modified."""
  22 
  23 
  24 class DriverRegistrationError(ValueError):
  25     """Raised when a format driver is requested but is not registered."""
  26 
  27 
  28 class FileOverwriteError(FileError):
  29     """Raised when Rasterio's CLI refuses to clobber output files."""
  30 
  31     def __init__(self, message):
  32         """Raise FileOverwriteError with message as hint."""
  33         super(FileOverwriteError, self).__init__('', hint=message)
  34 
  35 
  36 class RasterioIOError(IOError):
  37     """Raised when a dataset cannot be opened using one of the
  38     registered format drivers."""
  39 
  40 
  41 class NodataShadowWarning(UserWarning):
  42     """Warn that a dataset's nodata attribute is shadowing its alpha band."""
  43 
  44     def __str__(self):
  45         return ("The dataset's nodata attribute is shadowing "
  46                 "the alpha band. All masks will be determined "
  47                 "by the nodata attribute")
  48 
  49 
  50 class NotGeoreferencedWarning(UserWarning):
  51     """Warn that a dataset isn't georeferenced."""
  52 
  53 
  54 class GDALBehaviorChangeException(RuntimeError):
  55     """Raised when GDAL's behavior differs from the given arguments.  For
  56     example, antimeridian cutting is always on as of GDAL 2.2.0.  Users
  57     expecting it to be off will be presented with a MultiPolygon when the
  58     rest of their code expects a Polygon.
  59 
  60         # Raises an exception on GDAL >= 2.2.0
  61         rasterio.warp.transform_geometry(
  62             src_crs, dst_crs, antimeridian_cutting=False)
  63     """
  64 
  65 
  66 class GDALOptionNotImplementedError(RasterioError):
  67     """A dataset opening or dataset creation option can't be supported
  68 
  69     This will be raised from Rasterio's shim modules. For example, when
  70     a user passes arguments to open_dataset() that can't be evaluated
  71     by GDAL 1.x.
  72     """
  73 
  74 class GDALVersionError(RasterioError):
  75     """Raised if the runtime version of GDAL does not meet the required
  76     version of GDAL."""
  77 
  78 
  79 class WindowEvaluationError(ValueError):
  80     """Raised when window evaluation fails"""
  81 
  82 
  83 class RasterioDeprecationWarning(UserWarning):
  84     """Rasterio module deprecations"""
  85 
  86 
  87 class RasterBlockError(RasterioError):
  88     """Raised when raster block access fails"""
  89 
  90 
  91 class BandOverviewError(UserWarning):
  92     """Raised when a band overview access fails."""
  93 
  94 
  95 class WarpOptionsError(RasterioError):
  96     """Raised when options for a warp operation are invalid"""
  97 
  98 
  99 class UnsupportedOperation(RasterioError):
  100     """Raised when reading from a file opened in 'w' mode"""
  101 
  102 
  103 class OverviewCreationError(RasterioError):
  104     """Raised when creation of an overview fails"""
  105
  ```
  --- 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()
  
  ```
  
golden_diff: diff --git a/rasterio/errors.py b/rasterio/errors.py
  --- a/rasterio/errors.py
  +++ b/rasterio/errors.py
  @@ -102,3 +102,7 @@
   
   class OverviewCreationError(RasterioError):
       """Raised when creation of an overview fails"""
  +
  +
  +class DatasetAttributeError(RasterioError, NotImplementedError):
  +    """Raised when dataset attributes are misused"""
  
verification_info: {"golden_diff": "diff --git a/rasterio/errors.py b/rasterio/errors.py\n--- a/rasterio/errors.py\n+++ b/rasterio/errors.py\n@@ -102,3 +102,7 @@\n \n class OverviewCreationError(RasterioError):\n     \"\"\"Raised when creation of an overview fails\"\"\"\n+\n+\n+class DatasetAttributeError(RasterioError, NotImplementedError):\n+    \"\"\"Raised when dataset attributes are misused\"\"\"\n", "issue": "more explicit NotImplementedError messages in read mode ?\nIn wanting to set a GeoTIFF's CRS, I encountered [this](https://github.com/mapbox/rasterio/blob/master/rasterio/_base.pyx#L516) NotImplementedError when trying to run the following code:\r\n```\r\nwith rasterio.open(filepath) as src:\r\n    src.crs = \"EPSG:3857\"\r\n```\r\nThough in retrospect it is obvious the above will fail without explicitly specifying the proper  mode , i.e. `'r+'` in this case,  I was momentarily thrown off by the error and assumed something was wrong with my approach. Would a more explicit error message be useful here?\r\n\n", "before_files": [{"content": "\"\"\"Errors and Warnings.\"\"\"\n\nfrom click import FileError\n\n\nclass RasterioError(Exception):\n    \"\"\"Root exception class\"\"\"\n\n\nclass WindowError(RasterioError):\n    \"\"\"Raised when errors occur during window operations\"\"\"\n\n\nclass CRSError(ValueError):\n    \"\"\"Raised when a CRS string or mapping is invalid or cannot serve\n    to define a coordinate transformation.\"\"\"\n\n\nclass EnvError(RasterioError):\n    \"\"\"Raised when the state of GDAL/AWS environment cannot be created\n    or modified.\"\"\"\n\n\nclass DriverRegistrationError(ValueError):\n    \"\"\"Raised when a format driver is requested but is not registered.\"\"\"\n\n\nclass FileOverwriteError(FileError):\n    \"\"\"Raised when Rasterio's CLI refuses to clobber output files.\"\"\"\n\n    def __init__(self, message):\n        \"\"\"Raise FileOverwriteError with message as hint.\"\"\"\n        super(FileOverwriteError, self).__init__('', hint=message)\n\n\nclass RasterioIOError(IOError):\n    \"\"\"Raised when a dataset cannot be opened using one of the\n    registered format drivers.\"\"\"\n\n\nclass NodataShadowWarning(UserWarning):\n    \"\"\"Warn that a dataset's nodata attribute is shadowing its alpha band.\"\"\"\n\n    def __str__(self):\n        return (\"The dataset's nodata attribute is shadowing \"\n                \"the alpha band. All masks will be determined \"\n                \"by the nodata attribute\")\n\n\nclass NotGeoreferencedWarning(UserWarning):\n    \"\"\"Warn that a dataset isn't georeferenced.\"\"\"\n\n\nclass GDALBehaviorChangeException(RuntimeError):\n    \"\"\"Raised when GDAL's behavior differs from the given arguments.  For\n    example, antimeridian cutting is always on as of GDAL 2.2.0.  Users\n    expecting it to be off will be presented with a MultiPolygon when the\n    rest of their code expects a Polygon.\n\n        # Raises an exception on GDAL >= 2.2.0\n        rasterio.warp.transform_geometry(\n            src_crs, dst_crs, antimeridian_cutting=False)\n    \"\"\"\n\n\nclass GDALOptionNotImplementedError(RasterioError):\n    \"\"\"A dataset opening or dataset creation option can't be supported\n\n    This will be raised from Rasterio's shim modules. For example, when\n    a user passes arguments to open_dataset() that can't be evaluated\n    by GDAL 1.x.\n    \"\"\"\n\nclass GDALVersionError(RasterioError):\n    \"\"\"Raised if the runtime version of GDAL does not meet the required\n    version of GDAL.\"\"\"\n\n\nclass WindowEvaluationError(ValueError):\n    \"\"\"Raised when window evaluation fails\"\"\"\n\n\nclass RasterioDeprecationWarning(UserWarning):\n    \"\"\"Rasterio module deprecations\"\"\"\n\n\nclass RasterBlockError(RasterioError):\n    \"\"\"Raised when raster block access fails\"\"\"\n\n\nclass BandOverviewError(UserWarning):\n    \"\"\"Raised when a band overview access fails.\"\"\"\n\n\nclass WarpOptionsError(RasterioError):\n    \"\"\"Raised when options for a warp operation are invalid\"\"\"\n\n\nclass UnsupportedOperation(RasterioError):\n    \"\"\"Raised when reading from a file opened in 'w' mode\"\"\"\n\n\nclass OverviewCreationError(RasterioError):\n    \"\"\"Raised when creation of an overview fails\"\"\"\n", "path": "rasterio/errors.py"}], "after_files": [{"content": "\"\"\"Errors and Warnings.\"\"\"\n\nfrom click import FileError\n\n\nclass RasterioError(Exception):\n    \"\"\"Root exception class\"\"\"\n\n\nclass WindowError(RasterioError):\n    \"\"\"Raised when errors occur during window operations\"\"\"\n\n\nclass CRSError(ValueError):\n    \"\"\"Raised when a CRS string or mapping is invalid or cannot serve\n    to define a coordinate transformation.\"\"\"\n\n\nclass EnvError(RasterioError):\n    \"\"\"Raised when the state of GDAL/AWS environment cannot be created\n    or modified.\"\"\"\n\n\nclass DriverRegistrationError(ValueError):\n    \"\"\"Raised when a format driver is requested but is not registered.\"\"\"\n\n\nclass FileOverwriteError(FileError):\n    \"\"\"Raised when Rasterio's CLI refuses to clobber output files.\"\"\"\n\n    def __init__(self, message):\n        \"\"\"Raise FileOverwriteError with message as hint.\"\"\"\n        super(FileOverwriteError, self).__init__('', hint=message)\n\n\nclass RasterioIOError(IOError):\n    \"\"\"Raised when a dataset cannot be opened using one of the\n    registered format drivers.\"\"\"\n\n\nclass NodataShadowWarning(UserWarning):\n    \"\"\"Warn that a dataset's nodata attribute is shadowing its alpha band.\"\"\"\n\n    def __str__(self):\n        return (\"The dataset's nodata attribute is shadowing \"\n                \"the alpha band. All masks will be determined \"\n                \"by the nodata attribute\")\n\n\nclass NotGeoreferencedWarning(UserWarning):\n    \"\"\"Warn that a dataset isn't georeferenced.\"\"\"\n\n\nclass GDALBehaviorChangeException(RuntimeError):\n    \"\"\"Raised when GDAL's behavior differs from the given arguments.  For\n    example, antimeridian cutting is always on as of GDAL 2.2.0.  Users\n    expecting it to be off will be presented with a MultiPolygon when the\n    rest of their code expects a Polygon.\n\n        # Raises an exception on GDAL >= 2.2.0\n        rasterio.warp.transform_geometry(\n            src_crs, dst_crs, antimeridian_cutting=False)\n    \"\"\"\n\n\nclass GDALOptionNotImplementedError(RasterioError):\n    \"\"\"A dataset opening or dataset creation option can't be supported\n\n    This will be raised from Rasterio's shim modules. For example, when\n    a user passes arguments to open_dataset() that can't be evaluated\n    by GDAL 1.x.\n    \"\"\"\n\nclass GDALVersionError(RasterioError):\n    \"\"\"Raised if the runtime version of GDAL does not meet the required\n    version of GDAL.\"\"\"\n\n\nclass WindowEvaluationError(ValueError):\n    \"\"\"Raised when window evaluation fails\"\"\"\n\n\nclass RasterioDeprecationWarning(UserWarning):\n    \"\"\"Rasterio module deprecations\"\"\"\n\n\nclass RasterBlockError(RasterioError):\n    \"\"\"Raised when raster block access fails\"\"\"\n\n\nclass BandOverviewError(UserWarning):\n    \"\"\"Raised when a band overview access fails.\"\"\"\n\n\nclass WarpOptionsError(RasterioError):\n    \"\"\"Raised when options for a warp operation are invalid\"\"\"\n\n\nclass UnsupportedOperation(RasterioError):\n    \"\"\"Raised when reading from a file opened in 'w' mode\"\"\"\n\n\nclass OverviewCreationError(RasterioError):\n    \"\"\"Raised when creation of an overview fails\"\"\"\n\n\nclass DatasetAttributeError(RasterioError, NotImplementedError):\n    \"\"\"Raised when dataset attributes are misused\"\"\"\n", "path": "rasterio/errors.py"}]}