From 3ac2215ddb9452e7ebeee43a5eaadcd589c94530 Mon Sep 17 00:00:00 2001 From: Jan Cholasta Date: Tue, 7 Jun 2016 17:58:09 +0200 Subject: schema: generate client-side commands on demand Instead of pre-generating all command classes from API schema on API initialization and using them as plugins, use placeholder objects which generate the classes on demand. https://fedorahosted.org/freeipa/ticket/4739 Reviewed-By: David Kupka --- ipaclient/remote_plugins/schema.py | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) (limited to 'ipaclient/remote_plugins') diff --git a/ipaclient/remote_plugins/schema.py b/ipaclient/remote_plugins/schema.py index c817562fc..3a1394426 100644 --- a/ipaclient/remote_plugins/schema.py +++ b/ipaclient/remote_plugins/schema.py @@ -47,7 +47,7 @@ _PARAMS = { } -class SchemaCommand(Command): +class _SchemaCommand(Command): def __fix_default_from(self, param): api = self.api name = self.name @@ -76,14 +76,14 @@ class SchemaCommand(Command): return param.clone(default_from=DefaultFrom(callback, *keys)) def get_args(self): - for arg in super(SchemaCommand, self).get_args(): + for arg in super(_SchemaCommand, self).get_args(): if arg.default_from is not None: arg = self.__fix_default_from(arg) yield arg def get_options(self): skip = set() - for option in super(SchemaCommand, self).get_options(): + for option in super(_SchemaCommand, self).get_options(): if option.name in skip: continue if option.name in ('all', 'raw'): @@ -226,8 +226,31 @@ def _create_command(schema): return command +class _LazySchemaCommand(object): + def __init__(self, schema): + self.__schema = schema + self.__class = None + self.__module__ = None + + @property + def name(self): + return str(self.__schema['name']) + + bases = (_SchemaCommand,) + + def __call__(self, api): + if self.__class is None: + command = _create_command(self.__schema) + name = command.pop('name') + command = type(name, (_SchemaCommand,), command) + command.__module__ = self.__module__ + self.__class = command + + return self.__class(api) + + def _create_commands(schema): - return [_create_command(s) for s in schema] + return [_LazySchemaCommand(s) for s in schema] def _create_topic(schema): @@ -281,11 +304,9 @@ def get_package(api): sys.modules[module_name] = module for command in commands: - name = command.pop('name') - command = type(name, (SchemaCommand,), command) command.__module__ = module_name command = module.register()(command) - setattr(module, name, command) + setattr(module, command.name, command) for topic in topics: name = topic.pop('name') -- cgit