Repository: rasterio/rasterio

Issue:
rio info tests/data/float.tif aborts
`rio info tests/data/float.tif` 

returns 
`Aborted!`


Failing test case for this here: https://github.com/mapbox/rasterio/compare/master...brendan-ward:rio_info_abort_err

Aborts on both OSX and Travis (errors shown [here](https://travis-ci.org/brendan-ward/rasterio/jobs/260450827))


Discussion:

Resolving patch:
diff --git a/rasterio/rio/info.py b/rasterio/rio/info.py
--- a/rasterio/rio/info.py
+++ b/rasterio/rio/info.py
@@ -61,69 +61,67 @@ def info(ctx, input, aspect, indent, namespace, meta_member, verbose, bidx,
 
     Optionally print a single metadata item as a string.
     """
-    try:
-        with ctx.obj['env'], rasterio.open(input) as src:
-
-            info = dict(src.profile)
-            info['shape'] = (info['height'], info['width'])
-            info['bounds'] = src.bounds
-
-            if src.crs:
-                proj4 = src.crs.to_string()
-                if proj4.startswith('+init=epsg'):
-                    proj4 = proj4.split('=')[1].upper()
-                info['crs'] = proj4
-            else:
-                info['crs'] = None
-
-            info['res'] = src.res
-            info['colorinterp'] = [src.colorinterp(i).name
-                                   for i in src.indexes]
-            info['units'] = [units or None for units in src.units]
-            info['descriptions'] = src.descriptions
-            info['indexes'] = src.indexes
-            info['mask_flags'] = [[
-                flag.name for flag in flags] for flags in src.mask_flag_enums]
-
-            if proj4 != '':
-                info['lnglat'] = src.lnglat()
-
-            if verbose:
-                stats = [{'min': float(b.min()),
-                          'max': float(b.max()),
-                          'mean': float(b.mean())
-                          } for b in src.read(masked=masked)]
-                info['stats'] = stats
-
-                info['checksum'] = [src.checksum(i) for i in src.indexes]
-
-                gcps, crs = src.gcps
-                proj4 = crs.to_string()
-                if proj4.startswith('+init=epsg'):
-                    proj4 = proj4.split('=')[1].upper()
-                if gcps:
-                    info['gcps'] = {
-                        'crs': proj4, 'points': [p.asdict() for p in gcps]}
-
-            if aspect == 'meta':
-                if meta_member == 'stats':
-                    band = src.read(bidx, masked=masked)
-                    click.echo('%f %f %f' % (
-                        float(band.min()),
-                        float(band.max()),
-                        float(band.mean())))
-                elif meta_member == 'checksum':
-                    click.echo(str(src.checksum(bidx)))
-                elif meta_member:
-                    if isinstance(info[meta_member], (list, tuple)):
-                        click.echo(" ".join(map(str, info[meta_member])))
-                    else:
-                        click.echo(info[meta_member])
+    with ctx.obj['env'], rasterio.open(input) as src:
+
+        info = dict(src.profile)
+        info['shape'] = (info['height'], info['width'])
+        info['bounds'] = src.bounds
+
+        if src.crs:
+            proj4 = src.crs.to_string()
+            if proj4.startswith('+init=epsg'):
+                proj4 = proj4.split('=')[1].upper()
+            info['crs'] = proj4
+        else:
+            info['crs'] = None
+            proj4 = ''
+
+        info['res'] = src.res
+        info['colorinterp'] = [src.colorinterp(i).name
+                               for i in src.indexes]
+        info['units'] = [units or None for units in src.units]
+        info['descriptions'] = src.descriptions
+        info['indexes'] = src.indexes
+        info['mask_flags'] = [[
+            flag.name for flag in flags] for flags in src.mask_flag_enums]
+
+        if proj4 != '':
+            info['lnglat'] = src.lnglat()
+
+        if verbose:
+            stats = [{'min': float(b.min()),
+                      'max': float(b.max()),
+                      'mean': float(b.mean())
+                      } for b in src.read(masked=masked)]
+            info['stats'] = stats
+
+            info['checksum'] = [src.checksum(i) for i in src.indexes]
+
+            gcps, crs = src.gcps
+            proj4 = crs.to_string()
+            if proj4.startswith('+init=epsg'):
+                proj4 = proj4.split('=')[1].upper()
+            if gcps:
+                info['gcps'] = {
+                    'crs': proj4, 'points': [p.asdict() for p in gcps]}
+
+        if aspect == 'meta':
+            if meta_member == 'stats':
+                band = src.read(bidx, masked=masked)
+                click.echo('%f %f %f' % (
+                    float(band.min()),
+                    float(band.max()),
+                    float(band.mean())))
+            elif meta_member == 'checksum':
+                click.echo(str(src.checksum(bidx)))
+            elif meta_member:
+                if isinstance(info[meta_member], (list, tuple)):
+                    click.echo(" ".join(map(str, info[meta_member])))
                 else:
-                    click.echo(json.dumps(info, sort_keys=True, indent=indent))
+                    click.echo(info[meta_member])
+            else:
+                click.echo(json.dumps(info, sort_keys=True, indent=indent))
 
-            elif aspect == 'tags':
-                click.echo(
-                    json.dumps(src.tags(ns=namespace), indent=indent))
-    except Exception:
-        raise click.Abort()
+        elif aspect == 'tags':
+            click.echo(
+                json.dumps(src.tags(ns=namespace), indent=indent))


Test patch:
diff --git a/tests/test_rio_info.py b/tests/test_rio_info.py
--- a/tests/test_rio_info.py
+++ b/tests/test_rio_info.py
@@ -1,6 +1,4 @@
 import json
-import logging
-import sys
 
 import click
 from click.testing import CliRunner
@@ -365,10 +363,15 @@ def test_env():
 
 
 def test_info_err():
+    """Trying to get info of a directory raises an exception"""
     runner = CliRunner()
     result = runner.invoke(
         main_group, ['info', 'tests'])
-    assert result.exit_code == 1
+    assert result.exit_code == -1
+    assert result.exception
+    exc_str = str(result.exception)
+    # Note: text of exception changed after 2.1, don't test on full string
+    assert 'not ' in exc_str and ' a supported file format' in exc_str
 
 
 def test_info():
@@ -376,7 +379,18 @@ def test_info():
     result = runner.invoke(
         main_group, ['info', 'tests/data/RGB.byte.tif'])
     assert result.exit_code == 0
-    assert '"count": 3' in result.output
+    info = json.loads(result.output)
+    assert info['count'] == 3
+    assert info['dtype'] == 'uint8'
+    assert info['crs'] == 'EPSG:32618'
+
+    result = runner.invoke(
+        main_group, ['info', 'tests/data/float.tif'])
+    assert result.exit_code == 0
+    info = json.loads(result.output)
+    assert info['count'] == 1
+    assert info['dtype'] == 'float64'
+    assert info['crs'] == None
 
 
 def test_info_units():