diff --git a/skimage/io/_plugins/null_plugin.ini b/skimage/io/_plugins/null_plugin.ini index ddc45f33..9703aab0 100644 --- a/skimage/io/_plugins/null_plugin.ini +++ b/skimage/io/_plugins/null_plugin.ini @@ -1,3 +1,3 @@ [null] description = Default plugin that does nothing -provides = imshow, imread, _app_show +provides = imshow, imread, imsave, _app_show diff --git a/skimage/io/_plugins/null_plugin.py b/skimage/io/_plugins/null_plugin.py index 70bfd5d8..4eb7adf3 100644 --- a/skimage/io/_plugins/null_plugin.py +++ b/skimage/io/_plugins/null_plugin.py @@ -1,4 +1,4 @@ -__all__ = ['imshow', 'imread', '_app_show'] +__all__ = ['imshow', 'imread', 'imsave', '_app_show'] import warnings @@ -17,4 +17,9 @@ def imshow(*args, **kwargs): def imread(*args, **kwargs): warnings.warn(RuntimeWarning(message)) + +def imsave(*args, **kwargs): + warnings.warn(RuntimeWarning(message)) + + _app_show = imshow diff --git a/skimage/io/_plugins/plugin.py b/skimage/io/_plugins/plugin.py index 6657ebbc..42cf448e 100644 --- a/skimage/io/_plugins/plugin.py +++ b/skimage/io/_plugins/plugin.py @@ -25,9 +25,14 @@ plugin_module_name = {} plugin_meta_data = {} preferred_plugins = { - 'io': ['matplotlib', 'pil', 'qt', 'freeimage', 'null'] + 'all': ['matplotlib', 'pil', 'qt', 'freeimage', 'null'], + # Use PIL as the default imread plugin, since matplotlib (1.2.x) + # is buggy (flips PNGs around, returns bytes as floats, etc.) + 'imread': ['pil'], + 'imread.tiff': ['tifffile'], } + def _clear_plugins(): """Clear the plugin state to the default, i.e., where no plugins are loaded @@ -43,23 +48,24 @@ _clear_plugins() def _load_preferred_plugins(): # Load preferred plugin for each io function. - io_funcs = ['imsave', 'imshow', 'imread_collection', 'imread'] - for func in io_funcs: - for plugin in preferred_plugins['io']: - if plugin not in available_plugins: - continue - try: - use_plugin(plugin, kind=func) - break - except (ImportError, RuntimeError, OSError): - pass + io_types = ['imsave', 'imshow', 'imread_collection', 'imread'] + for p_type in io_types: + _set_plugin(p_type, preferred_plugins['all']) - # Use PIL as the default imread plugin, since matplotlib (1.2.x) - # is buggy (flips PNGs around, returns bytes as floats, etc.) - try: - use_plugin('pil', 'imread') - except ImportError: - pass + plugin_types = (p for p in preferred_plugins.keys() if p != 'all') + for p_type in plugin_types: + _set_plugin(p_type, preferred_plugins[p_type]) + + +def _set_plugin(plugin_type, plugin_list): + for plugin in plugin_list: + if plugin not in available_plugins: + continue + try: + use_plugin(plugin, kind=plugin_type) + break + except (ImportError, RuntimeError, OSError): + pass def reset_plugins(): diff --git a/skimage/io/tests/test_plugin.py b/skimage/io/tests/test_plugin.py index 53f105a2..fba1c5d0 100644 --- a/skimage/io/tests/test_plugin.py +++ b/skimage/io/tests/test_plugin.py @@ -1,3 +1,5 @@ +from contextlib import contextmanager + from numpy.testing import assert_equal, raises from skimage import io @@ -27,6 +29,16 @@ def teardown_module(): io.reset_plugins() +@contextmanager +def protect_preferred_plugins(): + """Contexts where `preferred_plugins` can be modified w/o side-effects.""" + preferred_plugins = plugin.preferred_plugins.copy() + try: + yield + finally: + plugin.preferred_plugins = preferred_plugins + + def test_read(): io.imread('test.png', as_grey=True, dtype='i4', plugin='test') @@ -93,12 +105,29 @@ def test_available(): assert 'test' in io.find_available_plugins(loaded=True) -def test_load_preferred_plugins(): +def test_load_preferred_plugins_all(): from skimage.io._plugins import null_plugin - plugin.preferred_plugins['io'] = ['null'] - plugin.reset_plugins() - plug, func = plugin.plugin_store['imshow'][0] - assert func == null_plugin.imshow + + with protect_preferred_plugins(): + plugin.preferred_plugins = {'all': ['null']} + plugin.reset_plugins() + + for plugin_type in ('imread', 'imsave', 'imshow'): + plug, func = plugin.plugin_store[plugin_type][0] + assert func == getattr(null_plugin, plugin_type) + + +def test_load_preferred_plugins_imread(): + from skimage.io._plugins import null_plugin + + with protect_preferred_plugins(): + plugin.preferred_plugins['imread'] = ['null'] + plugin.reset_plugins() + + plug, func = plugin.plugin_store['imread'][0] + assert func == null_plugin.imread + plug, func = plugin.plugin_store['imshow'][0] + assert func != null_plugin.imshow if __name__ == "__main__":