We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Profile class to deprecate affine key
This is a common pattern in some rasterio code, ironically intended as a way to prepare for the future by ensuring `Affine` objects get passed as the `transform` kwarg. 

```
    with rasterio.open(src_path) as src:
        opts = src.profile.copy()

    opts['transform'] = opts['affine']
```

With the merger of the `drop-dep` branch in PR #763,  we get a `KeyError: 'affine'`.

Adding `affine` to profile dictionary would maintain backwards compat but would lead to unavoidable warnings when kwarg unpacking with `open(..., **profile)`

**Proposed solution**: Modify the `rasterio.profiles.Profile` class to behave like a dict but deprecate the usage of the `affine` key (Warning on `__getitem__`, AttributeError on `__setitem__`). Then `src.profile` could return an instance of this class instead of a dict.

Continuation of the discussion started here: https://github.com/mapbox/rasterio/pull/763#issuecomment-229737519 but broken out into a separate issue.


--- 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/rio/info.py`
Content:
```
1 """$ rio info"""
2 
3 
4 import json
5 
6 import click
7 
8 import rasterio
9 import rasterio.crs
10 from rasterio.rio import options
11 
12 
13 @click.command(short_help="Print information about a data file.")
14 @options.file_in_arg
15 @click.option('--meta', 'aspect', flag_value='meta', default=True,
16               help="Show data file structure (default).")
17 @click.option('--tags', 'aspect', flag_value='tags',
18               help="Show data file tags.")
19 @click.option('--namespace', help="Select a tag namespace.")
20 @click.option('--indent', default=None, type=int,
21               help="Indentation level for pretty printed output")
22 # Options to pick out a single metadata item and print it as
23 # a string.
24 @click.option('--count', 'meta_member', flag_value='count',
25               help="Print the count of bands.")
26 @click.option('-t', '--dtype', 'meta_member', flag_value='dtype',
27               help="Print the dtype name.")
28 @click.option('--nodata', 'meta_member', flag_value='nodata',
29               help="Print the nodata value.")
30 @click.option('-f', '--format', '--driver', 'meta_member', flag_value='driver',
31               help="Print the format driver.")
32 @click.option('--shape', 'meta_member', flag_value='shape',
33               help="Print the (height, width) shape.")
34 @click.option('--height', 'meta_member', flag_value='height',
35               help="Print the height (number of rows).")
36 @click.option('--width', 'meta_member', flag_value='width',
37               help="Print the width (number of columns).")
38 @click.option('--crs', 'meta_member', flag_value='crs',
39               help="Print the CRS as a PROJ.4 string.")
40 @click.option('--bounds', 'meta_member', flag_value='bounds',
41               help="Print the boundary coordinates "
42                    "(left, bottom, right, top).")
43 @click.option('-r', '--res', 'meta_member', flag_value='res',
44               help="Print pixel width and height.")
45 @click.option('--lnglat', 'meta_member', flag_value='lnglat',
46               help="Print longitude and latitude at center.")
47 @click.option('--stats', 'meta_member', flag_value='stats',
48               help="Print statistics (min, max, mean) of a single band "
49                    "(use --bidx).")
50 @click.option('--checksum', 'meta_member', flag_value='checksum',
51               help="Print integer checksum of a single band "
52                    "(use --bidx).")
53 @click.option('-v', '--tell-me-more', '--verbose', is_flag=True,
54               help="Output extra information.")
55 @options.bidx_opt
56 @options.masked_opt
57 @click.pass_context
58 def info(ctx, input, aspect, indent, namespace, meta_member, verbose, bidx,
59          masked):
60     """Print metadata about the dataset as JSON.
61 
62     Optionally print a single metadata item as a string.
63     """
64     verbosity = ctx.obj.get('verbosity')
65     mode = 'r' if (verbose or meta_member == 'stats') else 'r-'
66     try:
67         with rasterio.Env(CPL_DEBUG=(verbosity > 2)):
68             with rasterio.open(input, mode) as src:
69                 info = src.profile
70                 info['shape'] = info['height'], info['width']
71                 info['bounds'] = src.bounds
72                 proj4 = src.crs.to_string()
73                 if proj4.startswith('+init=epsg'):
74                     proj4 = proj4.split('=')[1].upper()
75                 info['crs'] = proj4
76                 info['res'] = src.res
77                 info['colorinterp'] = [src.colorinterp(i).name
78                                        for i in src.indexes]
79                 if proj4 != '':
80                     info['lnglat'] = src.lnglat()
81                 if verbose:
82                     stats = [{'min': float(b.min()),
83                               'max': float(b.max()),
84                               'mean': float(b.mean())
85                               } for b in src.read(masked=masked)]
86                     info['stats'] = stats
87                     info['checksum'] = [src.checksum(i) for i in src.indexes]
88                 if aspect == 'meta':
89                     if meta_member == 'stats':
90                         band = src.read(bidx, masked=masked)
91                         click.echo('%f %f %f' % (
92                             float(band.min()),
93                             float(band.max()),
94                             float(band.mean())))
95                     elif meta_member == 'checksum':
96                         click.echo(str(src.checksum(bidx)))
97                     elif meta_member:
98                         if isinstance(info[meta_member], (list, tuple)):
99                             click.echo(" ".join(map(str, info[meta_member])))
100                         else:
101                             click.echo(info[meta_member])
102                     else:
103                         click.echo(json.dumps(info, indent=indent))
104                 elif aspect == 'tags':
105                     click.echo(
106                         json.dumps(src.tags(ns=namespace), indent=indent))
107     except Exception:
108         raise click.Abort()
109
```

Path: `rasterio/profiles.py`
Content:
```
1 """Raster dataset profiles."""
2 
3 from rasterio.dtypes import uint8
4 
5 
6 class Profile:
7     """Base class for Rasterio dataset profiles.
8 
9     Subclasses will declare a format driver and driver-specific
10     creation options.
11     """
12 
13     driver = None
14     defaults = {}
15 
16     def __call__(self, **kwargs):
17         """Return a mapping of keyword args for writing a new datasets.
18 
19         Example:
20 
21             profile = SomeProfile()
22             with rasterio.open('foo.tif', 'w', **profile()) as dst:
23                 # Write data ...
24         """
25         if kwargs.get('driver', self.driver) != self.driver:
26             raise ValueError(
27                 "Overriding this profile's driver is not allowed.")
28         profile = self.defaults.copy()
29         profile.update(**kwargs)
30         profile['driver'] = self.driver
31         return profile
32 
33 
34 class DefaultGTiffProfile(Profile):
35     """A tiled, band-interleaved, LZW-compressed, 8-bit GTiff profile."""
36 
37     driver = 'GTiff'
38     defaults = {
39         'interleave': 'band',
40         'tiled': True,
41         'blockxsize': 256,
42         'blockysize': 256,
43         'compress': 'lzw',
44         'nodata': 0,
45         'dtype': uint8
46     }
47 
48 
49 default_gtiff_profile = DefaultGTiffProfile()
50
```
--- 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()

```

diff --git a/rasterio/profiles.py b/rasterio/profiles.py
--- a/rasterio/profiles.py
+++ b/rasterio/profiles.py
@@ -1,41 +1,69 @@
 """Raster dataset profiles."""
 
+import warnings
+
+from rasterio.compat import UserDict
 from rasterio.dtypes import uint8
 
 
-class Profile:
+class Profile(UserDict):
     """Base class for Rasterio dataset profiles.
 
-    Subclasses will declare a format driver and driver-specific
-    creation options.
+    Subclasses will declare driver-specific creation options.
     """
 
-    driver = None
     defaults = {}
 
-    def __call__(self, **kwargs):
-        """Return a mapping of keyword args for writing a new datasets.
+    def __init__(self, data={}, **kwds):
+        """Create a new profile based on the class defaults, which are
+        overlaid with items from the `data` dict and keyword arguments."""
+        UserDict.__init__(self)
+        initdata = self.defaults.copy()
+        initdata.update(data)
+        initdata.update(**kwds)
+
+        if 'affine' in initdata and 'transform' in initdata:
+            warnings.warn("affine item is deprecated, use transform only",
+                          DeprecationWarning)
+            del initdata['affine']
+        elif 'affine' in initdata:
+            warnings.warn("affine item is deprecated, use transform instead",
+                          DeprecationWarning)
+            initdata['transform'] = initdata.pop('affine')
+
+        self.data.update(initdata)
+
+    def __getitem__(self, key):
+        """Like normal item access but with affine alias."""
+        if key == 'affine':
+            key = 'transform'
+            warnings.warn("affine item is deprecated, use transform instead",
+                          DeprecationWarning)
+        return self.data[key]
+
+    def __setitem__(self, key, val):
+        """Like normal item setter but forbidding affine item."""
+        if key == 'affine':
+            raise TypeError("affine key is prohibited")
+        self.data[key] = val
 
-        Example:
+    def __call__(self, **kwds):
+        """Return a mapping of keyword args.
 
-            profile = SomeProfile()
-            with rasterio.open('foo.tif', 'w', **profile()) as dst:
-                # Write data ...
+        DEPRECATED.
         """
-        if kwargs.get('driver', self.driver) != self.driver:
-            raise ValueError(
-                "Overriding this profile's driver is not allowed.")
-        profile = self.defaults.copy()
-        profile.update(**kwargs)
-        profile['driver'] = self.driver
+        warnings.warn("__call__() is deprecated, use mapping methods instead",
+                      DeprecationWarning)
+        profile = self.data.copy()
+        profile.update(**kwds)
         return profile
 
 
 class DefaultGTiffProfile(Profile):
-    """A tiled, band-interleaved, LZW-compressed, 8-bit GTiff profile."""
+    """Tiled, band-interleaved, LZW-compressed, 8-bit GTiff."""
 
-    driver = 'GTiff'
     defaults = {
+        'driver': 'GTiff',
         'interleave': 'band',
         'tiled': True,
         'blockxsize': 256,
diff --git a/rasterio/rio/info.py b/rasterio/rio/info.py
--- a/rasterio/rio/info.py
+++ b/rasterio/rio/info.py
@@ -66,7 +66,7 @@
     try:
         with rasterio.Env(CPL_DEBUG=(verbosity > 2)):
             with rasterio.open(input, mode) as src:
-                info = src.profile
+                info = dict(src.profile)
                 info['shape'] = info['height'], info['width']
                 info['bounds'] = src.bounds
                 proj4 = src.crs.to_string()

{"golden_diff": "diff --git a/rasterio/profiles.py b/rasterio/profiles.py\n--- a/rasterio/profiles.py\n+++ b/rasterio/profiles.py\n@@ -1,41 +1,69 @@\n \"\"\"Raster dataset profiles.\"\"\"\n \n+import warnings\n+\n+from rasterio.compat import UserDict\n from rasterio.dtypes import uint8\n \n \n-class Profile:\n+class Profile(UserDict):\n     \"\"\"Base class for Rasterio dataset profiles.\n \n-    Subclasses will declare a format driver and driver-specific\n-    creation options.\n+    Subclasses will declare driver-specific creation options.\n     \"\"\"\n \n-    driver = None\n     defaults = {}\n \n-    def __call__(self, **kwargs):\n-        \"\"\"Return a mapping of keyword args for writing a new datasets.\n+    def __init__(self, data={}, **kwds):\n+        \"\"\"Create a new profile based on the class defaults, which are\n+        overlaid with items from the `data` dict and keyword arguments.\"\"\"\n+        UserDict.__init__(self)\n+        initdata = self.defaults.copy()\n+        initdata.update(data)\n+        initdata.update(**kwds)\n+\n+        if 'affine' in initdata and 'transform' in initdata:\n+            warnings.warn(\"affine item is deprecated, use transform only\",\n+                          DeprecationWarning)\n+            del initdata['affine']\n+        elif 'affine' in initdata:\n+            warnings.warn(\"affine item is deprecated, use transform instead\",\n+                          DeprecationWarning)\n+            initdata['transform'] = initdata.pop('affine')\n+\n+        self.data.update(initdata)\n+\n+    def __getitem__(self, key):\n+        \"\"\"Like normal item access but with affine alias.\"\"\"\n+        if key == 'affine':\n+            key = 'transform'\n+            warnings.warn(\"affine item is deprecated, use transform instead\",\n+                          DeprecationWarning)\n+        return self.data[key]\n+\n+    def __setitem__(self, key, val):\n+        \"\"\"Like normal item setter but forbidding affine item.\"\"\"\n+        if key == 'affine':\n+            raise TypeError(\"affine key is prohibited\")\n+        self.data[key] = val\n \n-        Example:\n+    def __call__(self, **kwds):\n+        \"\"\"Return a mapping of keyword args.\n \n-            profile = SomeProfile()\n-            with rasterio.open('foo.tif', 'w', **profile()) as dst:\n-                # Write data ...\n+        DEPRECATED.\n         \"\"\"\n-        if kwargs.get('driver', self.driver) != self.driver:\n-            raise ValueError(\n-                \"Overriding this profile's driver is not allowed.\")\n-        profile = self.defaults.copy()\n-        profile.update(**kwargs)\n-        profile['driver'] = self.driver\n+        warnings.warn(\"__call__() is deprecated, use mapping methods instead\",\n+                      DeprecationWarning)\n+        profile = self.data.copy()\n+        profile.update(**kwds)\n         return profile\n \n \n class DefaultGTiffProfile(Profile):\n-    \"\"\"A tiled, band-interleaved, LZW-compressed, 8-bit GTiff profile.\"\"\"\n+    \"\"\"Tiled, band-interleaved, LZW-compressed, 8-bit GTiff.\"\"\"\n \n-    driver = 'GTiff'\n     defaults = {\n+        'driver': 'GTiff',\n         'interleave': 'band',\n         'tiled': True,\n         'blockxsize': 256,\ndiff --git a/rasterio/rio/info.py b/rasterio/rio/info.py\n--- a/rasterio/rio/info.py\n+++ b/rasterio/rio/info.py\n@@ -66,7 +66,7 @@\n     try:\n         with rasterio.Env(CPL_DEBUG=(verbosity > 2)):\n             with rasterio.open(input, mode) as src:\n-                info = src.profile\n+                info = dict(src.profile)\n                 info['shape'] = info['height'], info['width']\n                 info['bounds'] = src.bounds\n                 proj4 = src.crs.to_string()\n", "issue": "Profile class to deprecate affine key\nThis is a common pattern in some rasterio code, ironically intended as a way to prepare for the future by ensuring `Affine` objects get passed as the `transform` kwarg. \n\n```\n    with rasterio.open(src_path) as src:\n        opts = src.profile.copy()\n\n    opts['transform'] = opts['affine']\n```\n\nWith the merger of the `drop-dep` branch in PR #763,  we get a `KeyError: 'affine'`.\n\nAdding `affine` to profile dictionary would maintain backwards compat but would lead to unavoidable warnings when kwarg unpacking with `open(..., **profile)`\n\n**Proposed solution**: Modify the `rasterio.profiles.Profile` class to behave like a dict but deprecate the usage of the `affine` key (Warning on `__getitem__`, AttributeError on `__setitem__`). Then `src.profile` could return an instance of this class instead of a dict.\n\nContinuation of the discussion started here: https://github.com/mapbox/rasterio/pull/763#issuecomment-229737519 but broken out into a separate issue.\n\n", "before_files": [{"content": "\"\"\"$ rio info\"\"\"\n\n\nimport json\n\nimport click\n\nimport rasterio\nimport rasterio.crs\nfrom rasterio.rio import options\n\n\n@click.command(short_help=\"Print information about a data file.\")\n@options.file_in_arg\n@click.option('--meta', 'aspect', flag_value='meta', default=True,\n              help=\"Show data file structure (default).\")\n@click.option('--tags', 'aspect', flag_value='tags',\n              help=\"Show data file tags.\")\n@click.option('--namespace', help=\"Select a tag namespace.\")\n@click.option('--indent', default=None, type=int,\n              help=\"Indentation level for pretty printed output\")\n# Options to pick out a single metadata item and print it as\n# a string.\n@click.option('--count', 'meta_member', flag_value='count',\n              help=\"Print the count of bands.\")\n@click.option('-t', '--dtype', 'meta_member', flag_value='dtype',\n              help=\"Print the dtype name.\")\n@click.option('--nodata', 'meta_member', flag_value='nodata',\n              help=\"Print the nodata value.\")\n@click.option('-f', '--format', '--driver', 'meta_member', flag_value='driver',\n              help=\"Print the format driver.\")\n@click.option('--shape', 'meta_member', flag_value='shape',\n              help=\"Print the (height, width) shape.\")\n@click.option('--height', 'meta_member', flag_value='height',\n              help=\"Print the height (number of rows).\")\n@click.option('--width', 'meta_member', flag_value='width',\n              help=\"Print the width (number of columns).\")\n@click.option('--crs', 'meta_member', flag_value='crs',\n              help=\"Print the CRS as a PROJ.4 string.\")\n@click.option('--bounds', 'meta_member', flag_value='bounds',\n              help=\"Print the boundary coordinates \"\n                   \"(left, bottom, right, top).\")\n@click.option('-r', '--res', 'meta_member', flag_value='res',\n              help=\"Print pixel width and height.\")\n@click.option('--lnglat', 'meta_member', flag_value='lnglat',\n              help=\"Print longitude and latitude at center.\")\n@click.option('--stats', 'meta_member', flag_value='stats',\n              help=\"Print statistics (min, max, mean) of a single band \"\n                   \"(use --bidx).\")\n@click.option('--checksum', 'meta_member', flag_value='checksum',\n              help=\"Print integer checksum of a single band \"\n                   \"(use --bidx).\")\n@click.option('-v', '--tell-me-more', '--verbose', is_flag=True,\n              help=\"Output extra information.\")\n@options.bidx_opt\n@options.masked_opt\n@click.pass_context\ndef info(ctx, input, aspect, indent, namespace, meta_member, verbose, bidx,\n         masked):\n    \"\"\"Print metadata about the dataset as JSON.\n\n    Optionally print a single metadata item as a string.\n    \"\"\"\n    verbosity = ctx.obj.get('verbosity')\n    mode = 'r' if (verbose or meta_member == 'stats') else 'r-'\n    try:\n        with rasterio.Env(CPL_DEBUG=(verbosity > 2)):\n            with rasterio.open(input, mode) as src:\n                info = src.profile\n                info['shape'] = info['height'], info['width']\n                info['bounds'] = src.bounds\n                proj4 = src.crs.to_string()\n                if proj4.startswith('+init=epsg'):\n                    proj4 = proj4.split('=')[1].upper()\n                info['crs'] = proj4\n                info['res'] = src.res\n                info['colorinterp'] = [src.colorinterp(i).name\n                                       for i in src.indexes]\n                if proj4 != '':\n                    info['lnglat'] = src.lnglat()\n                if verbose:\n                    stats = [{'min': float(b.min()),\n                              'max': float(b.max()),\n                              'mean': float(b.mean())\n                              } for b in src.read(masked=masked)]\n                    info['stats'] = stats\n                    info['checksum'] = [src.checksum(i) for i in src.indexes]\n                if aspect == 'meta':\n                    if meta_member == 'stats':\n                        band = src.read(bidx, masked=masked)\n                        click.echo('%f %f %f' % (\n                            float(band.min()),\n                            float(band.max()),\n                            float(band.mean())))\n                    elif meta_member == 'checksum':\n                        click.echo(str(src.checksum(bidx)))\n                    elif meta_member:\n                        if isinstance(info[meta_member], (list, tuple)):\n                            click.echo(\" \".join(map(str, info[meta_member])))\n                        else:\n                            click.echo(info[meta_member])\n                    else:\n                        click.echo(json.dumps(info, indent=indent))\n                elif aspect == 'tags':\n                    click.echo(\n                        json.dumps(src.tags(ns=namespace), indent=indent))\n    except Exception:\n        raise click.Abort()\n", "path": "rasterio/rio/info.py"}, {"content": "\"\"\"Raster dataset profiles.\"\"\"\n\nfrom rasterio.dtypes import uint8\n\n\nclass Profile:\n    \"\"\"Base class for Rasterio dataset profiles.\n\n    Subclasses will declare a format driver and driver-specific\n    creation options.\n    \"\"\"\n\n    driver = None\n    defaults = {}\n\n    def __call__(self, **kwargs):\n        \"\"\"Return a mapping of keyword args for writing a new datasets.\n\n        Example:\n\n            profile = SomeProfile()\n            with rasterio.open('foo.tif', 'w', **profile()) as dst:\n                # Write data ...\n        \"\"\"\n        if kwargs.get('driver', self.driver) != self.driver:\n            raise ValueError(\n                \"Overriding this profile's driver is not allowed.\")\n        profile = self.defaults.copy()\n        profile.update(**kwargs)\n        profile['driver'] = self.driver\n        return profile\n\n\nclass DefaultGTiffProfile(Profile):\n    \"\"\"A tiled, band-interleaved, LZW-compressed, 8-bit GTiff profile.\"\"\"\n\n    driver = 'GTiff'\n    defaults = {\n        'interleave': 'band',\n        'tiled': True,\n        'blockxsize': 256,\n        'blockysize': 256,\n        'compress': 'lzw',\n        'nodata': 0,\n        'dtype': uint8\n    }\n\n\ndefault_gtiff_profile = DefaultGTiffProfile()\n", "path": "rasterio/profiles.py"}], "after_files": [{"content": "\"\"\"$ rio info\"\"\"\n\n\nimport json\n\nimport click\n\nimport rasterio\nimport rasterio.crs\nfrom rasterio.rio import options\n\n\n@click.command(short_help=\"Print information about a data file.\")\n@options.file_in_arg\n@click.option('--meta', 'aspect', flag_value='meta', default=True,\n              help=\"Show data file structure (default).\")\n@click.option('--tags', 'aspect', flag_value='tags',\n              help=\"Show data file tags.\")\n@click.option('--namespace', help=\"Select a tag namespace.\")\n@click.option('--indent', default=None, type=int,\n              help=\"Indentation level for pretty printed output\")\n# Options to pick out a single metadata item and print it as\n# a string.\n@click.option('--count', 'meta_member', flag_value='count',\n              help=\"Print the count of bands.\")\n@click.option('-t', '--dtype', 'meta_member', flag_value='dtype',\n              help=\"Print the dtype name.\")\n@click.option('--nodata', 'meta_member', flag_value='nodata',\n              help=\"Print the nodata value.\")\n@click.option('-f', '--format', '--driver', 'meta_member', flag_value='driver',\n              help=\"Print the format driver.\")\n@click.option('--shape', 'meta_member', flag_value='shape',\n              help=\"Print the (height, width) shape.\")\n@click.option('--height', 'meta_member', flag_value='height',\n              help=\"Print the height (number of rows).\")\n@click.option('--width', 'meta_member', flag_value='width',\n              help=\"Print the width (number of columns).\")\n@click.option('--crs', 'meta_member', flag_value='crs',\n              help=\"Print the CRS as a PROJ.4 string.\")\n@click.option('--bounds', 'meta_member', flag_value='bounds',\n              help=\"Print the boundary coordinates \"\n                   \"(left, bottom, right, top).\")\n@click.option('-r', '--res', 'meta_member', flag_value='res',\n              help=\"Print pixel width and height.\")\n@click.option('--lnglat', 'meta_member', flag_value='lnglat',\n              help=\"Print longitude and latitude at center.\")\n@click.option('--stats', 'meta_member', flag_value='stats',\n              help=\"Print statistics (min, max, mean) of a single band \"\n                   \"(use --bidx).\")\n@click.option('--checksum', 'meta_member', flag_value='checksum',\n              help=\"Print integer checksum of a single band \"\n                   \"(use --bidx).\")\n@click.option('-v', '--tell-me-more', '--verbose', is_flag=True,\n              help=\"Output extra information.\")\n@options.bidx_opt\n@options.masked_opt\n@click.pass_context\ndef info(ctx, input, aspect, indent, namespace, meta_member, verbose, bidx,\n         masked):\n    \"\"\"Print metadata about the dataset as JSON.\n\n    Optionally print a single metadata item as a string.\n    \"\"\"\n    verbosity = ctx.obj.get('verbosity')\n    mode = 'r' if (verbose or meta_member == 'stats') else 'r-'\n    try:\n        with rasterio.Env(CPL_DEBUG=(verbosity > 2)):\n            with rasterio.open(input, mode) as src:\n                info = dict(src.profile)\n                info['shape'] = info['height'], info['width']\n                info['bounds'] = src.bounds\n                proj4 = src.crs.to_string()\n                if proj4.startswith('+init=epsg'):\n                    proj4 = proj4.split('=')[1].upper()\n                info['crs'] = proj4\n                info['res'] = src.res\n                info['colorinterp'] = [src.colorinterp(i).name\n                                       for i in src.indexes]\n                if proj4 != '':\n                    info['lnglat'] = src.lnglat()\n                if verbose:\n                    stats = [{'min': float(b.min()),\n                              'max': float(b.max()),\n                              'mean': float(b.mean())\n                              } for b in src.read(masked=masked)]\n                    info['stats'] = stats\n                    info['checksum'] = [src.checksum(i) for i in src.indexes]\n                if aspect == 'meta':\n                    if meta_member == 'stats':\n                        band = src.read(bidx, masked=masked)\n                        click.echo('%f %f %f' % (\n                            float(band.min()),\n                            float(band.max()),\n                            float(band.mean())))\n                    elif meta_member == 'checksum':\n                        click.echo(str(src.checksum(bidx)))\n                    elif meta_member:\n                        if isinstance(info[meta_member], (list, tuple)):\n                            click.echo(\" \".join(map(str, info[meta_member])))\n                        else:\n                            click.echo(info[meta_member])\n                    else:\n                        click.echo(json.dumps(info, indent=indent))\n                elif aspect == 'tags':\n                    click.echo(\n                        json.dumps(src.tags(ns=namespace), indent=indent))\n    except Exception:\n        raise click.Abort()\n", "path": "rasterio/rio/info.py"}, {"content": "\"\"\"Raster dataset profiles.\"\"\"\n\nimport warnings\n\nfrom rasterio.compat import UserDict\nfrom rasterio.dtypes import uint8\n\n\nclass Profile(UserDict):\n    \"\"\"Base class for Rasterio dataset profiles.\n\n    Subclasses will declare driver-specific creation options.\n    \"\"\"\n\n    defaults = {}\n\n    def __init__(self, data={}, **kwds):\n        \"\"\"Create a new profile based on the class defaults, which are\n        overlaid with items from the `data` dict and keyword arguments.\"\"\"\n        UserDict.__init__(self)\n        initdata = self.defaults.copy()\n        initdata.update(data)\n        initdata.update(**kwds)\n\n        if 'affine' in initdata and 'transform' in initdata:\n            warnings.warn(\"affine item is deprecated, use transform only\",\n                          DeprecationWarning)\n            del initdata['affine']\n        elif 'affine' in initdata:\n            warnings.warn(\"affine item is deprecated, use transform instead\",\n                          DeprecationWarning)\n            initdata['transform'] = initdata.pop('affine')\n\n        self.data.update(initdata)\n\n    def __getitem__(self, key):\n        \"\"\"Like normal item access but with affine alias.\"\"\"\n        if key == 'affine':\n            key = 'transform'\n            warnings.warn(\"affine item is deprecated, use transform instead\",\n                          DeprecationWarning)\n        return self.data[key]\n\n    def __setitem__(self, key, val):\n        \"\"\"Like normal item setter but forbidding affine item.\"\"\"\n        if key == 'affine':\n            raise TypeError(\"affine key is prohibited\")\n        self.data[key] = val\n\n    def __call__(self, **kwds):\n        \"\"\"Return a mapping of keyword args.\n\n        DEPRECATED.\n        \"\"\"\n        warnings.warn(\"__call__() is deprecated, use mapping methods instead\",\n                      DeprecationWarning)\n        profile = self.data.copy()\n        profile.update(**kwds)\n        return profile\n\n\nclass DefaultGTiffProfile(Profile):\n    \"\"\"Tiled, band-interleaved, LZW-compressed, 8-bit GTiff.\"\"\"\n\n    defaults = {\n        'driver': 'GTiff',\n        'interleave': 'band',\n        'tiled': True,\n        'blockxsize': 256,\n        'blockysize': 256,\n        'compress': 'lzw',\n        'nodata': 0,\n        'dtype': uint8\n    }\n\n\ndefault_gtiff_profile = DefaultGTiffProfile()\n", "path": "rasterio/profiles.py"}]}