plugable: Specify plugin base classes and modules using API properties

https://fedorahosted.org/freeipa/ticket/3090

Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
This commit is contained in:
Jan Cholasta
2015-06-15 13:36:26 +00:00
parent 4b277d0477
commit 2b12bca660
4 changed files with 36 additions and 18 deletions

View File

@@ -899,16 +899,16 @@ else:
class API(plugable.API):
def __init__(self, allowed):
super(API, self).__init__(allowed, ['ipalib.plugins.*'])
def bootstrap(self, parser=None, **overrides):
super(API, self).bootstrap(parser, **overrides)
bases = (Command, Object, Method, Backend, Updater)
@property
def modules(self):
result = ('ipalib.plugins.*',)
if self.env.in_server:
self.modules.append('ipaserver.plugins.*')
result += ('ipaserver.plugins.*',)
if self.env.context in ('installer', 'updates'):
self.modules.append('ipaserver.install.plugins.*')
result += ('ipaserver.install.plugins.*',)
return result
def create_api(mode='dummy'):
@@ -926,7 +926,7 @@ def create_api(mode='dummy'):
- `backend.Backend`
"""
api = API((Command, Object, Method, Backend, Updater))
api = API()
if mode is not None:
api.env.mode = mode
assert mode != 'production'

View File

@@ -306,24 +306,31 @@ class API(ReadOnly):
register = Registrar()
def __init__(self, allowed, modules):
def __init__(self):
super(API, self).__init__()
self.__plugins = {base: {} for base in allowed}
self.modules = modules
self.__plugins = {}
self.__done = set()
self.env = Env()
@property
def bases(self):
raise NotImplementedError
@property
def modules(self):
raise NotImplementedError
def __len__(self):
"""
Return the number of plugin namespaces in this API object.
"""
return len(self.__plugins)
return len(self.bases)
def __iter__(self):
"""
Iterate (in ascending order) through plugin namespace names.
"""
return (base.__name__ for base in self.__plugins)
return (base.__name__ for base in self.bases)
def __contains__(self, name):
"""
@@ -614,10 +621,11 @@ class API(ReadOnly):
# Find the base class or raise SubclassError:
found = False
for (base, sub_d) in self.__plugins.iteritems():
for base in self.bases:
if not issubclass(klass, base):
continue
sub_d = self.__plugins.setdefault(base, {})
found = True
if sub_d.get(klass.__name__) is klass:
@@ -647,7 +655,7 @@ class API(ReadOnly):
if not found:
raise errors.PluginSubclassError(
plugin=klass,
bases=self.__plugins.keys(),
bases=self.bases,
)
def finalize(self):
@@ -664,8 +672,9 @@ class API(ReadOnly):
plugins = {}
plugin_info = {}
for base, sub_d in self.__plugins.iteritems():
for base in self.bases:
name = base.__name__
sub_d = self.__plugins.get(base, {})
members = []
for klass in sub_d.itervalues():

View File

@@ -121,7 +121,12 @@ class Advice(Plugin):
raise NotImplementedError
advise_api = API((Advice,), ('ipaserver.advise.plugins.*',))
class AdviseAPI(API):
bases = (Advice,)
modules = ('ipaserver.advise.plugins.*',)
advise_api = AdviseAPI()
class IpaAdvise(admintool.AdminTool):

View File

@@ -202,7 +202,11 @@ class test_API(ClassChecker):
def method(self, n):
return n + 1
api = plugable.API([base0, base1], [])
class API(plugable.API):
bases = (base0, base1)
modules = ()
api = API()
api.env.mode = 'unit_test'
api.env.in_tree = True
r = api.add_plugin