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
|
- Change the
|
||||||
:class:`~stevedore.dispatch.NamedDispatchExtensionManager` to ignore
|
:class:`~stevedore.dispatch.NamedDispatchExtensionManager` to ignore
|
||||||
missing extensions (:issue:`14`).
|
missing extensions (:issue:`14`).
|
||||||
|
- Add ``__getitem__`` to
|
||||||
|
:class:`~stevedore.extension.ExtensionManager` for looking up
|
||||||
|
individual plugins by name (:issue:`15`).
|
||||||
|
|
||||||
0.8
|
0.8
|
||||||
|
|
||||||
|
@ -55,6 +55,7 @@ class ExtensionManager(object):
|
|||||||
self.extensions = self._load_plugins(invoke_on_load,
|
self.extensions = self._load_plugins(invoke_on_load,
|
||||||
invoke_args,
|
invoke_args,
|
||||||
invoke_kwds)
|
invoke_kwds)
|
||||||
|
self._extensions_by_name = None
|
||||||
|
|
||||||
ENTRY_POINT_CACHE = {}
|
ENTRY_POINT_CACHE = {}
|
||||||
|
|
||||||
@ -93,6 +94,9 @@ class ExtensionManager(object):
|
|||||||
|
|
||||||
def names(self):
|
def names(self):
|
||||||
"Returns the names of the discovered extensions"
|
"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]
|
return [e.name for e in self.extensions]
|
||||||
|
|
||||||
def map(self, func, *args, **kwds):
|
def map(self, func, *args, **kwds):
|
||||||
@ -133,3 +137,17 @@ class ExtensionManager(object):
|
|||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
return iter(self.extensions)
|
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,
|
def __init__(self, namespace, name,
|
||||||
invoke_on_load=False, invoke_args=(), invoke_kwds={}):
|
invoke_on_load=False, invoke_args=(), invoke_kwds={}):
|
||||||
|
self._name = name
|
||||||
super(HookManager, self).__init__(
|
super(HookManager, self).__init__(
|
||||||
namespace,
|
namespace,
|
||||||
[name],
|
[name],
|
||||||
@ -30,3 +31,14 @@ class HookManager(NamedExtensionManager):
|
|||||||
invoke_args=invoke_args,
|
invoke_args=invoke_args,
|
||||||
invoke_kwds=invoke_kwds,
|
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']
|
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():
|
def test_load_multiple_times_entry_points():
|
||||||
# We expect to get the same EntryPoint object because we save them
|
# We expect to get the same EntryPoint object because we save them
|
||||||
# in the cache.
|
# in the cache.
|
||||||
|
@ -11,3 +11,33 @@ def test_hook():
|
|||||||
)
|
)
|
||||||
assert len(em.extensions) == 1
|
assert len(em.extensions) == 1
|
||||||
assert em.names() == ['t1']
|
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