Repository: SciTools/cartopy

Issue:
Shapereader doctest failure
Currently seeing this on Travis on the latest py2k build:
```
024     >>> filename = shapereader.natural_earth(resolution='110m'
025     ...                                      category='physical'
026     ...                                      name='geography_regions_points')
027     >>> reader = shapereader.Reader(filename)
028     >>> len(reader)
029     3
030     >>> records = list(reader.records())
031     >>> print(type(records[0]))
032     <class 'cartopy.io.shapereader.Record'>
033     >>> print(sorted(records[0].attributes.keys()))
Expected:
    ['comment', ... 'name', 'name_alt', ... 'region', ...]
Got:
    [u'comment', u'featurecla', u'label', u'lat_y', u'long_x', u'min_zoom', u'name', u'name_alt', u'name_ar', u'name_bn', u'name_de', u'name_el', u'name_en', u'name_es', u'name_fr', u'name_hi', u'name_hu', u'name_id', u'name_it', u'name_ja', u'name_ko', u'name_nl', u'name_pl', u'name_pt', u'name_ru', u'name_sv', u'name_tr', u'name_vi', u'name_zh', u'ne_id', u'region', u'scalerank', u'subregion', u'wdid_score', u'wikidataid']
```

So it looks like the problem is the leading `u`...but does anyone know if this is new behavior from a library (and who) or if it's a problem with the doctest runner?


Discussion:
It looks like it's using pyshp 2.0.0, and the first lines of its changes is:

> - Full support for unicode text, with custom encoding, and exception handling.
> - Means that the Reader returns unicode, and the Writer accepts unicode. 
FWIW: Long term, I'd like to move away from the shapereader implementation altogether - Fiona and geopandas have both arrived since that code was written, and they do a better job of documenting and performance.

Resolving patch:
diff --git a/lib/cartopy/io/shapereader.py b/lib/cartopy/io/shapereader.py
--- a/lib/cartopy/io/shapereader.py
+++ b/lib/cartopy/io/shapereader.py
@@ -30,8 +30,8 @@
     >>> records = list(reader.records())
     >>> print(type(records[0]))
     <class 'cartopy.io.shapereader.Record'>
-    >>> print(sorted(records[0].attributes.keys()))
-    ['comment', ... 'name', 'name_alt', ... 'region', ...]
+    >>> print(', '.join(str(r) for r in sorted(records[0].attributes.keys())))
+    comment, ... name, name_alt, ... region, ...
     >>> print(records[0].attributes['name'])
     Niagara Falls
     >>> geoms = list(reader.geometries())
diff --git a/lib/cartopy/mpl/geoaxes.py b/lib/cartopy/mpl/geoaxes.py
--- a/lib/cartopy/mpl/geoaxes.py
+++ b/lib/cartopy/mpl/geoaxes.py
@@ -236,18 +236,18 @@ class GeoAxes(matplotlib.axes.Axes):
     when created with the *projection* keyword. For example::
 
         # Set up a standard map for latlon data.
-        geo_axes = pyplot.axes(projection=cartopy.crs.PlateCarree())
+        geo_axes = plt.axes(projection=cartopy.crs.PlateCarree())
 
         # Set up an OSGB map.
-        geo_axes = pyplot.subplot(2, 2, 1, projection=cartopy.crs.OSGB())
+        geo_axes = plt.subplot(2, 2, 1, projection=cartopy.crs.OSGB())
 
     When a source projection is provided to one of it's plotting methods,
     using the *transform* keyword, the standard Matplotlib plot result is
     transformed from source coordinates to the target projection. For example::
 
         # Plot latlon data on an OSGB map.
-        pyplot.axes(projection=cartopy.crs.OSGB())
-        pyplot.contourf(x, y, data, transform=cartopy.crs.PlateCarree())
+        plt.axes(projection=cartopy.crs.OSGB())
+        plt.contourf(x, y, data, transform=cartopy.crs.PlateCarree())
 
     """
     def __init__(self, *args, **kwargs):


Test patch: