NamedExtensionManager: call a callback when some names cannot be found

This will allow users to find out errors in their code that are currently
silently ignored.

Change-Id: I405511f9acc5319b1e4373be084f6a7c97556acf
This commit is contained in:
Cyril Roelandt 2016-06-24 19:37:16 +02:00
parent f33b810403
commit 6f81f6f1c1
2 changed files with 34 additions and 0 deletions

View File

@ -1,5 +1,9 @@
import logging
from .extension import ExtensionManager
LOG = logging.getLogger(__name__)
class NamedExtensionManager(ExtensionManager):
"""Loads only the named extensions.
@ -34,6 +38,10 @@ class NamedExtensionManager(ExtensionManager):
when this is called (when an entrypoint fails to load) are
(manager, entrypoint, exception)
:type on_load_failure_callback: function
:param on_missing_entrypoints_callback: Callback function that will be
called when one or more names cannot be found. The provided argument
will be a subset of the 'names' parameter.
:type on_missing_entrypoints_callback: function
:param verify_requirements: Use setuptools to enforce the
dependencies of the plugin(s) being loaded. Defaults to False.
:type verify_requirements: bool
@ -44,6 +52,7 @@ class NamedExtensionManager(ExtensionManager):
invoke_on_load=False, invoke_args=(), invoke_kwds={},
name_order=False, propagate_map_exceptions=False,
on_load_failure_callback=None,
on_missing_entrypoints_callback=None,
verify_requirements=False):
self._init_attributes(
namespace, names, name_order=name_order,
@ -53,6 +62,13 @@ class NamedExtensionManager(ExtensionManager):
invoke_args,
invoke_kwds,
verify_requirements)
missing_entrypoints = set(names) - set([e.name for e in extensions])
if missing_entrypoints:
if on_missing_entrypoints_callback:
on_missing_entrypoints_callback(missing_entrypoints)
else:
LOG.warning('Could not load %s' %
', '.join(missing_entrypoints))
self._init_plugins(extensions)
@classmethod

View File

@ -1,8 +1,10 @@
"""Tests for failure loading callback
"""
from testtools.matchers import GreaterThan
import mock
from stevedore import extension
from stevedore import named
from stevedore.tests import utils
@ -23,3 +25,19 @@ class TestCallback(utils.TestCase):
for manager, entrypoint, error in errors:
self.assertIs(manager, em)
self.assertIsInstance(error, (IOError, ImportError))
@mock.patch('stevedore.named.NamedExtensionManager._load_plugins')
def test_missing_entrypoints_callback(self, load_fn):
errors = set()
def callback(names):
errors.update(names)
load_fn.return_value = [
extension.Extension('foo', None, None, None)
]
named.NamedExtensionManager('stevedore.test.extension',
names=['foo', 'bar'],
invoke_on_load=True,
on_missing_entrypoints_callback=callback)
self.assertEqual(errors, {'bar'})