Check the names of plugins before importing them
Update NamedExtensionManager to check the names of the plugins before loading any code to avoid importing anything we are not going to use. Fixes issue #4 Change-Id: I27b19cb42ca3d165ce45953281b82e394c4539a2 Signed-off-by: Doug Hellmann <doug.hellmann@dreamhost.com>
This commit is contained in:
parent
42fbe31c4f
commit
83098c78d0
@ -6,6 +6,9 @@ dev
|
||||
|
||||
- Ignore AssertionError exceptions generated when plugins are
|
||||
loaded.
|
||||
- Update :class:`~stevedore.named.NamedExtensionManager` to check
|
||||
the name of a plugin before loading its code to avoid importing
|
||||
anything we are not going to use.
|
||||
|
||||
0.7.2
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
from .enabled import EnabledExtensionManager
|
||||
from .extension import ExtensionManager
|
||||
|
||||
|
||||
class NamedExtensionManager(EnabledExtensionManager):
|
||||
class NamedExtensionManager(ExtensionManager):
|
||||
"""Loads only the named extensions.
|
||||
|
||||
This is useful for explictly enabling extensions in a
|
||||
@ -26,12 +26,20 @@ class NamedExtensionManager(EnabledExtensionManager):
|
||||
|
||||
def __init__(self, namespace, names,
|
||||
invoke_on_load=False, invoke_args=(), invoke_kwds={}):
|
||||
def check(ep):
|
||||
return ep.name in names
|
||||
self._names = names
|
||||
super(NamedExtensionManager, self).__init__(
|
||||
namespace,
|
||||
check,
|
||||
invoke_on_load=invoke_on_load,
|
||||
invoke_args=invoke_args,
|
||||
invoke_kwds=invoke_kwds,
|
||||
)
|
||||
|
||||
def _load_one_plugin(self, ep, invoke_on_load, invoke_args, invoke_kwds):
|
||||
# Check the name before going any further to prevent
|
||||
# undesirable code from being loaded at all if we are not
|
||||
# going to use it.
|
||||
if ep.name not in self._names:
|
||||
return None
|
||||
return super(NamedExtensionManager, self)._load_one_plugin(
|
||||
ep, invoke_on_load, invoke_args, invoke_kwds,
|
||||
)
|
||||
|
@ -1,13 +1,37 @@
|
||||
from stevedore import named
|
||||
|
||||
import mock
|
||||
|
||||
|
||||
def test_named():
|
||||
em = named.NamedExtensionManager(
|
||||
'stevedore.test.extension',
|
||||
['t1'],
|
||||
names=['t1'],
|
||||
invoke_on_load=True,
|
||||
invoke_args=('a',),
|
||||
invoke_kwds={'b': 'B'},
|
||||
)
|
||||
assert len(em.extensions) == 1
|
||||
assert em.names() == ['t1']
|
||||
actual = em.names()
|
||||
assert actual == ['t1']
|
||||
|
||||
|
||||
def test_enabled_before_load():
|
||||
# Set up the constructor for the FauxExtension to cause an
|
||||
# AssertionError so the test fails if the class is instantiated,
|
||||
# which should only happen if it is loaded before the name of the
|
||||
# extension is compared against the names that should be loaded by
|
||||
# the manager.
|
||||
init_name = 'stevedore.tests.test_extension.FauxExtension.__init__'
|
||||
with mock.patch(init_name) as m:
|
||||
m.side_effect = AssertionError
|
||||
em = named.NamedExtensionManager(
|
||||
'stevedore.test.extension',
|
||||
# Look for an extension that does not exist so the
|
||||
# __init__ we mocked should never be invoked.
|
||||
names=['no-such-extension'],
|
||||
invoke_on_load=True,
|
||||
invoke_args=('a',),
|
||||
invoke_kwds={'b': 'B'},
|
||||
)
|
||||
actual = em.names()
|
||||
assert actual == []
|
||||
|
Loading…
Reference in New Issue
Block a user