Remove plugin functionality from io.py. Implement setting default plugins and querying the plugins available.

This commit is contained in:
Stefan van der Walt
2009-11-01 12:38:36 +02:00
parent e7d6875cab
commit 940f318b31
4 changed files with 124 additions and 38 deletions
+1
View File
@@ -4,6 +4,7 @@ import pil_plugin
import matplotlib_plugin
from plugin import register as register_plugin
from sift import *
from collection import *
+4 -38
View File
@@ -1,40 +1,6 @@
__all__ = ['imread', 'imsave', 'imshow']
from scikits.image.io.plugin import plugin_store
def _call_plugin(kind, *args, **kwargs):
"""Find the appropriate plugin of 'kind' and execute it.
Parameters
----------
kind : {'imshow', 'imsave', 'imread'}
Function to look up.
plugin : str, optional
Plugin to load. Defaults to None, in which case the first
matching plugin is used.
*args, **kwargs : arguments and keyword arguments
Passed to the plugin function.
"""
if not kind in plugin_store:
raise ValueError('Invalid function (%s) requested.' % kind)
plugin_funcs = plugin_store[kind]
if len(plugin_funcs) == 0:
raise RuntimeError('No suitable plugin registered for %s' % kind)
plugin = kwargs.pop('plugin', None)
if plugin is None:
_, func = plugin_funcs[0]
else:
try:
func = [f for (p,f) in plugin_funcs if p == plugin][0]
except IndexError:
raise RuntimeError('Could not find the plugin "%s" for %s.' % \
(plugin, kind))
return func(*args, **kwargs)
from scikits.image.io import plugin as _plugin
def imread(fname, as_grey=False, dtype=None, plugin=None, flatten=None,
**plugin_args):
@@ -78,7 +44,7 @@ def imread(fname, as_grey=False, dtype=None, plugin=None, flatten=None,
if flatten is not None:
as_grey = flatten
return _call_plugin('read', fname, as_grey=as_grey, dtype=dtype,
return _plugin.call('read', fname, as_grey=as_grey, dtype=dtype,
plugin=plugin, **plugin_args)
def imsave(fname, arr, plugin=None, **plugin_args):
@@ -101,7 +67,7 @@ def imsave(fname, arr, plugin=None, **plugin_args):
Passed to the given plugin.
"""
return _call_plugin('save', fname, arr, plugin=plugin, **plugin_args)
return _plugin.call('save', fname, arr, plugin=plugin, **plugin_args)
def imshow(arr, plugin=None, **plugin_args):
"""Display an image.
@@ -121,4 +87,4 @@ def imshow(arr, plugin=None, **plugin_args):
Passed to the given plugin.
"""
return _call_plugin('show', arr, plugin=plugin, **plugin_args)
return _plugin.call('show', arr, plugin=plugin, **plugin_args)
+106
View File
@@ -2,6 +2,10 @@
"""
__all__ = ['register', 'use']
import warnings
plugin_store = {'read': [],
'save': [],
'show': []}
@@ -35,3 +39,105 @@ def register(name, **kwds):
raise ValueError('Can only register functions as plugins.')
plugin_store[kind].append((name, func))
def call(kind, *args, **kwargs):
"""Find the appropriate plugin of 'kind' and execute it.
Parameters
----------
kind : {'show', 'save', 'read'}
Function to look up.
plugin : str, optional
Plugin to load. Defaults to None, in which case the first
matching plugin is used.
*args, **kwargs : arguments and keyword arguments
Passed to the plugin function.
"""
if not kind in plugin_store:
raise ValueError('Invalid function (%s) requested.' % kind)
plugin_funcs = plugin_store[kind]
if len(plugin_funcs) == 0:
raise RuntimeError('No suitable plugin registered for %s' % kind)
plugin = kwargs.pop('plugin', None)
if plugin is None:
_, func = plugin_funcs[0]
else:
try:
func = [f for (p,f) in plugin_funcs if p == plugin][0]
except IndexError:
raise RuntimeError('Could not find the plugin "%s" for %s.' % \
(plugin, kind))
return func(*args, **kwargs)
def use(name, kind=None):
"""Set the default plugin for a specified operation.
Parameters
----------
name : str
Name of plugin.
kind : {'save', 'read', 'show'}, optional
Set the plugin for this function. By default,
the plugin is set for all functions.
Examples
--------
Use Python Imaging Library to read images:
>>> from scikits.image.io import plugin
>>> plugin.use('PIL', 'read')
"""
if kind is None:
kind = plugin_store.keys()
else:
kind = [kind]
for k in kind:
if not k in plugin_store:
raise RuntimeError("Could not find plugin for '%s'" % k)
funcs = plugin_store[k]
# Shuffle the plugins so that the requested plugin stands first
# in line
funcs = [(n, f) for (n, f) in funcs if n == name] + \
[(n, f) for (n, f) in funcs if n != name]
n, f = funcs[0]
if not n == name:
warnings.warn(RuntimeWarning('Could not set plugin "%s" for'
' function "%s".' % (name, k)))
plugin_store[k] = funcs
def available(kind=None):
"""List available plugins.
Parameters
----------
kind : {'show', 'save', 'read'}, optional
Display the plugin list for the given function type. If not specified,
return a dictionary with the plugins for all functions.
"""
if kind is None:
kind = plugin_store.keys()
else:
kind = [kind]
d = {}
for k in kind:
if not k in plugin_store:
raise ValueError('No function "%s" exists in the plugin registry.'
% kind)
d[k] = [name for (name, func) in plugin_store[k]]
return d
+13
View File
@@ -18,9 +18,13 @@ def show(arr, plugin_arg=None):
assert arr == [1, 2, 3]
assert plugin_arg == (1, 2)
def show_other(arr):
return "other"
def setup_module(self):
self.backup_plugin_store = deepcopy(plugin.plugin_store)
plugin.register('test', read=read, save=save, show=show)
plugin.register('other', show=show_other)
def teardown_module(self):
plugin.plugin_store = self.backup_plugin_store
@@ -35,5 +39,14 @@ class TestPlugin:
def test_show(self):
io.imshow([1, 2, 3], plugin_arg=(1, 2), plugin='test')
def test_use(self):
plugin.use('other', 'show')
assert io.imshow(None) == 'other'
def test_available(self):
plugin.use('other', 'show')
d = plugin.available('show')
assert d['show'][0] == 'other'
if __name__ == "__main__":
run_module_suite()