Repository: SciTools/cartopy

Issue:
PIL is an unspecified dependency of cartopy
`pip install cartopy` doesn't pull in PIL or Pillow, but it could if they were added to setup.py.



Discussion:
We've got a few layers of requirements, which you can see at https://github.com/SciTools/cartopy/tree/master/requirements. For instance, matplotlib is not a dependency on cartopy either (but if you want the matplotlib interface, you will need it).
I didn't check, but does cartopy actually import without PIL? It's hard to know what to do about this one - we could change it so that all of the optional dependencies are also installed when pip installing...

I experience the same issue after installation through pip, and no, cartopy does not import without PIL:

``` python
[julien@altair figures]$ python2 -c 'import cartopy'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/home/julien/.local/lib/python2.7/site-packages/cartopy/__init__.py", line 111, in <module>
    import cartopy.feature
  File "/home/julien/.local/lib/python2.7/site-packages/cartopy/feature.py", line 32, in <module>
    from cartopy.io.ogc_clients import WFSGeometrySource
  File "/home/julien/.local/lib/python2.7/site-packages/cartopy/io/ogc_clients.py", line 43, in <module>
    from PIL import Image
ImportError: No module named PIL
```

PIL/Pillow is used here:

```
lib/cartopy/tests/test_img_nest.py:from PIL import Image
lib/cartopy/tests/mpl/test_images.py:from PIL import Image
lib/cartopy/io/ogc_clients.py:from PIL import Image
lib/cartopy/io/img_tiles.py:from PIL import Image
lib/cartopy/io/img_nest.py:from PIL import Image
```

They are not optional in those cases, though the functionality there is not necessarily required. @pelson it's up to you whether you prefer the hard dependency or changing those files.

> @pelson it's up to you whether you prefer the hard dependency or changing those files.

I'm happy for you to make that call too. If I had to lean one way or the other, I'd be inclined to stop importing `ocg_clients` when `cartopy` is imported.


Resolving patch:
diff --git a/lib/cartopy/feature.py b/lib/cartopy/feature.py
--- a/lib/cartopy/feature.py
+++ b/lib/cartopy/feature.py
@@ -29,7 +29,6 @@
 import shapely.geometry
 import six
 
-from cartopy.io.ogc_clients import WFSGeometrySource
 import cartopy.io.shapereader as shapereader
 import cartopy.crs
 
@@ -298,6 +297,8 @@ class WFSFeature(Feature):
     A class capable of drawing a collection of geometries
     obtained from an OGC Web Feature Service (WFS).
 
+    This feature requires additional dependencies. If installed via pip,
+    try ``pip install cartopy[ows]``.
     """
     def __init__(self, wfs, features, **kwargs):
         """
@@ -315,6 +316,12 @@ def __init__(self, wfs, features, **kwargs):
             Keyword arguments to be used when drawing this feature.
 
         """
+        try:
+            from cartopy.io.ogc_clients import WFSGeometrySource
+        except ImportError as e:
+            six.raise_from(ImportError(
+                'WFSFeature requires additional dependencies. If installed '
+                'via pip, try `pip install cartopy[ows]`.\n'), e)
 
         self.source = WFSGeometrySource(wfs, features)
         crs = self.source.default_projection()


Test patch: