Repository: scikit-image/scikit-image

Issue:
Pooch Dependency Issue
The following merged PR added dependency to pooch 1.3.0 in data module:
https://github.com/scikit-image/scikit-image/pull/5105/files

The current implementation checks if pooch is installed by trying to import it:

https://github.com/scikit-image/scikit-image/blob/0862e5630a00c151566260f02d118f4ee46bb351/skimage/data/__init__.py#L114-L120

Then uses it as if it's v1.3.0:

https://github.com/scikit-image/scikit-image/blob/0862e5630a00c151566260f02d118f4ee46bb351/skimage/data/__init__.py#L149-L150

This raises error if an older version of pooch such as 1.2.0 is installed.

The code is always executed since data module is imported in skimage init:

https://github.com/scikit-image/scikit-image/blob/0862e5630a00c151566260f02d118f4ee46bb351/skimage/__init__.py#L135

So you get the error even if you don't use data, hence did not install the scikit-image[data] extra.


Discussion:
Yes. I think this is a bug.

If we want to make pooch a soft dependency, then we should check for the version and not use pooch if it is lower than our minimum required specification.

Otherwise, we should make a hard dependency (which I don't think will happen since it was never the intent)
If you have an interest in making the pull request, please tag me and I will take part in the review process.

I would like to send a PR. We can use `pooch.__version__`, but comparing it with what we need is tricky. Do you have a suggestion for this? Another option is putting pooch.create inside a try-catch.
Yes version management is tricky. 

However, I think a good comment in the requirements file to ensure it is kept in sync is likely ok.

We can have a birectional comment in both files. Keeping two hardcoded locations is doable.

Resolving patch:
diff --git a/skimage/data/__init__.py b/skimage/data/__init__.py
--- a/skimage/data/__init__.py
+++ b/skimage/data/__init__.py
@@ -5,6 +5,7 @@
  - http://sipi.usc.edu/database/database.php
 
 """
+from distutils.version import LooseVersion
 from warnings import warn
 import numpy as np
 import shutil
@@ -52,7 +53,6 @@
            'text',
            'retina',
            'rocket',
-           'rough_wall',
            'shepp_logan_phantom',
            'skin',
            'stereo_motorcycle']
@@ -114,6 +114,13 @@ def _has_hash(path, expected_hash):
 def create_image_fetcher():
     try:
         import pooch
+        pooch_version = pooch.__version__.lstrip('v')
+        retry = {'retry_if_failed': 3}
+        # Keep version check in synch with
+        # scikit-image/requirements/optional.txt
+        if LooseVersion(pooch_version) < LooseVersion('1.3.0'):
+            # we need a more recent version of pooch to retry
+            retry = {}
     except ImportError:
         # Without pooch, fallback on the standard data directory
         # which for now, includes a few limited data samples
@@ -124,8 +131,8 @@ def create_image_fetcher():
     # remove `.dev` with a `+` if it exists.
     # This helps pooch understand that it should look in master
     # to find the required files
-    pooch_version = __version__.replace('.dev', '+')
-    if '+' in pooch_version:
+    skimage_version_for_pooch = __version__.replace('.dev', '+')
+    if '+' in skimage_version_for_pooch:
         url = ("https://github.com/scikit-image/scikit-image/raw/"
                "{version}/skimage/")
     else:
@@ -142,11 +149,14 @@ def create_image_fetcher():
         # With a version qualifier
         path=pooch.os_cache("scikit-image"),
         base_url=url,
-        version=pooch_version,
+        version=skimage_version_for_pooch,
         env="SKIMAGE_DATADIR",
         registry=registry,
         urls=registry_urls,
-        retry_if_failed=3,
+        # Note: this should read `retry_if_failed=3,`, but we generate that
+        # dynamically at import time above, in case installed pooch is a less
+        # recent version
+        **retry,
     )
 
     data_dir = osp.join(str(image_fetcher.abspath), 'data')


Test patch: