diff --git a/neutron_lib/api/extensions.py b/neutron_lib/api/extensions.py index ccd0676..246d550 100644 --- a/neutron_lib/api/extensions.py +++ b/neutron_lib/api/extensions.py @@ -106,7 +106,8 @@ class ExtensionDescriptor(object): def get_plugin_interface(self): """Returns an abstract class which defines contract for the plugin. - The abstract class should inherit from extensions.PluginInterface, + The abstract class should inherit from + neutron_lib.services.base.ServicePluginBase. Methods in this abstract class should be decorated as abstractmethod """ diff --git a/neutron_lib/services/base.py b/neutron_lib/services/base.py index e6bd2fe..5c92cf8 100644 --- a/neutron_lib/services/base.py +++ b/neutron_lib/services/base.py @@ -15,32 +15,7 @@ import abc import six -@six.add_metaclass(abc.ABCMeta) -class _PluginInterface(object): - - @classmethod - def __subclasshook__(cls, klass): - """Checking plugin class. - - The __subclasshook__ method is a class method - that will be called every time a class is tested - using issubclass(klass, _PluginInterface). - In that case, it will check that every method - marked with the abstractmethod decorator is - provided by the plugin class. - """ - - if not cls.__abstractmethods__: - return NotImplemented - - for method in cls.__abstractmethods__: - if any(method in base.__dict__ for base in klass.__mro__): - continue - return NotImplemented - return True - - -class _WorkerSupportServiceMixin(object): +class WorkerBase(object): @property def _workers(self): @@ -74,11 +49,31 @@ class _WorkerSupportServiceMixin(object): @six.add_metaclass(abc.ABCMeta) -class ServicePluginBase(_PluginInterface, - _WorkerSupportServiceMixin): +class ServicePluginBase(WorkerBase): """Define base interface for any Advanced Service plugin.""" supported_extension_aliases = [] + @classmethod + def __subclasshook__(cls, klass): + """Checking plugin class. + + The __subclasshook__ method is a class method + that will be called every time a class is tested + using issubclass(klass, ServicePluginBase). + In that case, it will check that every method + marked with the abstractmethod decorator is + provided by the plugin class. + """ + + if not cls.__abstractmethods__: + return NotImplemented + + for method in cls.__abstractmethods__: + if any(method in base.__dict__ for base in klass.__mro__): + continue + return NotImplemented + return True + @abc.abstractmethod def get_plugin_type(self): """Return one of predefined service types. diff --git a/neutron_lib/tests/unit/services/test_base.py b/neutron_lib/tests/unit/services/test_base.py index d73c67e..97d3dc8 100644 --- a/neutron_lib/tests/unit/services/test_base.py +++ b/neutron_lib/tests/unit/services/test_base.py @@ -16,7 +16,7 @@ from neutron_lib.services import base from neutron_lib.tests import _base as test_base -class _Worker(base._WorkerSupportServiceMixin): +class _Worker(base.WorkerBase): pass @@ -43,14 +43,21 @@ class Test_WorkerSupportServiceMixin(test_base.BaseTestCase): self.assertSequenceEqual(workers, self.worker.get_workers()) -class Test_PluginInterface(test_base.BaseTestCase): +class TestPluginInterface(test_base.BaseTestCase): + + class ServicePluginStub(base.ServicePluginBase): + def get_plugin_type(self): + pass + + def get_plugin_description(self): + pass def test_issubclass_hook(self): - class A(object): + class A(TestPluginInterface.ServicePluginStub): def f(self): pass - class B(base._PluginInterface): + class B(base.ServicePluginBase): @abc.abstractmethod def f(self): pass @@ -62,18 +69,18 @@ class Test_PluginInterface(test_base.BaseTestCase): def f(self): pass - class B(base._PluginInterface): + class B(base.ServicePluginBase): def f(self): pass self.assertFalse(issubclass(A, B)) def test_issubclass_hook_not_all_methods_implemented(self): - class A(object): + class A(TestPluginInterface.ServicePluginStub): def f(self): pass - class B(base._PluginInterface): + class B(base.ServicePluginBase): @abc.abstractmethod def f(self): pass diff --git a/releasenotes/notes/public-service-classes-e52d7c79a075b799.yaml b/releasenotes/notes/public-service-classes-e52d7c79a075b799.yaml new file mode 100644 index 0000000..cfb3e4c --- /dev/null +++ b/releasenotes/notes/public-service-classes-e52d7c79a075b799.yaml @@ -0,0 +1,10 @@ +--- +features: + - The ``neutron_lib.api.extensions.ExtensionDescriptor`` class's + ``get_plugin_interface`` method now formally only supports + ``neutron_lib.services.base.ServicePluginBase``. This change reflects + the existing usage by consumers as almost all are returning + instances of ``ServicePluginBase`` already. + - The class ``WorkerBase`` is now available and provides the same + functionality that's provided by + ``neutron.worker.WorkerSupportServiceMixin``.