Add ExtensionManager.__getitem__
Allow extensions to be accessed directly by name. Fixes issue #15 Signed-off-by: Doug Hellmann <doug.hellmann@dreamhost.com>
This commit is contained in:
parent
52572efd4a
commit
69e17801a3
@ -12,6 +12,9 @@ dev
|
||||
- Change the
|
||||
:class:`~stevedore.dispatch.NamedDispatchExtensionManager` to ignore
|
||||
missing extensions (:issue:`14`).
|
||||
- Add ``__getitem__`` to
|
||||
:class:`~stevedore.extension.ExtensionManager` for looking up
|
||||
individual plugins by name (:issue:`15`).
|
||||
|
||||
0.8
|
||||
|
||||
|
@ -55,6 +55,7 @@ class ExtensionManager(object):
|
||||
self.extensions = self._load_plugins(invoke_on_load,
|
||||
invoke_args,
|
||||
invoke_kwds)
|
||||
self._extensions_by_name = None
|
||||
|
||||
ENTRY_POINT_CACHE = {}
|
||||
|
||||
@ -93,6 +94,9 @@ class ExtensionManager(object):
|
||||
|
||||
def names(self):
|
||||
"Returns the names of the discovered extensions"
|
||||
# We want to return the names of the extensions in the order
|
||||
# they would be used by map(), since some subclasses change
|
||||
# that order.
|
||||
return [e.name for e in self.extensions]
|
||||
|
||||
def map(self, func, *args, **kwds):
|
||||
@ -133,3 +137,17 @@ class ExtensionManager(object):
|
||||
|
||||
def __iter__(self):
|
||||
return iter(self.extensions)
|
||||
|
||||
def __getitem__(self, name):
|
||||
"""Return the named extension.
|
||||
|
||||
Accessing an ExtensionManager as a dictionary (``em['name']``)
|
||||
produces the :class:`Extension` instance with the
|
||||
specified name.
|
||||
"""
|
||||
if self._extensions_by_name is None:
|
||||
d = {}
|
||||
for e in self.extensions:
|
||||
d[e.name] = e
|
||||
self._extensions_by_name = d
|
||||
return self._extensions_by_name[name]
|
||||
|
@ -23,6 +23,7 @@ class HookManager(NamedExtensionManager):
|
||||
|
||||
def __init__(self, namespace, name,
|
||||
invoke_on_load=False, invoke_args=(), invoke_kwds={}):
|
||||
self._name = name
|
||||
super(HookManager, self).__init__(
|
||||
namespace,
|
||||
[name],
|
||||
@ -30,3 +31,14 @@ class HookManager(NamedExtensionManager):
|
||||
invoke_args=invoke_args,
|
||||
invoke_kwds=invoke_kwds,
|
||||
)
|
||||
|
||||
def __getitem__(self, name):
|
||||
"""Return the named extensions.
|
||||
|
||||
Accessing a HookManager as a dictionary (``em['name']``)
|
||||
produces a list of the :class:`Extension` instance(s) with the
|
||||
specified name, in the order they would be invoked by map().
|
||||
"""
|
||||
if name != self._name:
|
||||
raise KeyError(name)
|
||||
return self.extensions
|
||||
|
@ -18,6 +18,22 @@ def test_detect_plugins():
|
||||
assert names == ['t1', 't2']
|
||||
|
||||
|
||||
def test_get_by_name():
|
||||
em = extension.ExtensionManager('stevedore.test.extension')
|
||||
e = em['t1']
|
||||
assert e.name == 't1'
|
||||
|
||||
|
||||
def test_get_by_name_missing():
|
||||
em = extension.ExtensionManager('stevedore.test.extension')
|
||||
try:
|
||||
em['t3']
|
||||
except KeyError:
|
||||
pass
|
||||
else:
|
||||
assert False, 'Failed to raise KeyError'
|
||||
|
||||
|
||||
def test_load_multiple_times_entry_points():
|
||||
# We expect to get the same EntryPoint object because we save them
|
||||
# in the cache.
|
||||
|
@ -11,3 +11,33 @@ def test_hook():
|
||||
)
|
||||
assert len(em.extensions) == 1
|
||||
assert em.names() == ['t1']
|
||||
|
||||
|
||||
def test_get_by_name():
|
||||
em = hook.HookManager(
|
||||
'stevedore.test.extension',
|
||||
't1',
|
||||
invoke_on_load=True,
|
||||
invoke_args=('a',),
|
||||
invoke_kwds={'b': 'B'},
|
||||
)
|
||||
e_list = em['t1']
|
||||
assert len(e_list) == 1
|
||||
e = e_list[0]
|
||||
assert e.name == 't1'
|
||||
|
||||
|
||||
def test_get_by_name_missing():
|
||||
em = hook.HookManager(
|
||||
'stevedore.test.extension',
|
||||
't1',
|
||||
invoke_on_load=True,
|
||||
invoke_args=('a',),
|
||||
invoke_kwds={'b': 'B'},
|
||||
)
|
||||
try:
|
||||
em['t2']
|
||||
except KeyError:
|
||||
pass
|
||||
else:
|
||||
assert False, 'Failed to raise KeyError'
|
||||
|
Loading…
Reference in New Issue
Block a user