diff --git a/ipalib/cli.py b/ipalib/cli.py index fb2fd95f4..9eb3c0920 100644 --- a/ipalib/cli.py +++ b/ipalib/cli.py @@ -705,7 +705,7 @@ class CLI(object): del kw[param.name] except KeyError: pass - (args, options) = cmd.params_2_args_options(kw) + (args, options) = cmd.params_2_args_options(**kw) cmd.output_for_cli(self.api.Backend.textui, result, *args, **options) def set_defaults(self, cmd, kw): @@ -784,11 +784,8 @@ class CLI(object): (kwc, args) = parser.parse_args( list(self.cmd_argv[1:]), KWCollector() ) - kw = kwc.__todict__() - arg_kw = cmd.args_to_kw(*args) - assert set(arg_kw).intersection(kw) == set() - kw.update(arg_kw) - return kw + options = kwc.__todict__() + return cmd.args_options_2_params(*args, **options) def build_parser(self, cmd): parser = optparse.OptionParser( diff --git a/ipalib/frontend.py b/ipalib/frontend.py index b38d376db..640b01f92 100644 --- a/ipalib/frontend.py +++ b/ipalib/frontend.py @@ -78,7 +78,6 @@ class Command(plugable.Plugin): 'args', 'options', 'params', - 'args_to_kw', 'params_2_args_options', 'args_options_2_params', 'output_for_cli', @@ -90,60 +89,23 @@ class Command(plugable.Plugin): params = None output_for_cli = None - def __call__(self, *args, **kw): + def __call__(self, *args, **options): """ Perform validation and then execute the command. If not in a server context, the call will be forwarded over XML-RPC and the executed an the nearest IPA server. """ - self.debug(make_repr(self.name, *args, **kw)) - if len(args) > 0: - arg_kw = self.args_to_kw(*args) - assert set(arg_kw).intersection(kw) == set() - kw.update(arg_kw) - kw = self.normalize(**kw) - kw = self.convert(**kw) - kw.update(self.get_default(**kw)) - self.validate(**kw) - (args, options) = self.params_2_args_options(kw) + params = self.args_options_2_params(*args, **options) + params = self.normalize(**params) + params = self.convert(**params) + params.update(self.get_default(**params)) + self.validate(**params) + (args, options) = self.params_2_args_options(**params) result = self.run(*args, **options) self.debug('%s result: %r', self.name, result) return result - def args_to_kw(self, *values): - """ - Map positional into keyword arguments. - """ - if self.max_args is not None and len(values) > self.max_args: - if self.max_args == 0: - raise errors.ArgumentError(self, 'takes no arguments') - if self.max_args == 1: - raise errors.ArgumentError(self, 'takes at most 1 argument') - raise errors.ArgumentError(self, - 'takes at most %d arguments' % len(self.args) - ) - return dict(self.__args_to_kw_iter(values)) - - def __args_to_kw_iter(self, values): - """ - Generator used by `Command.args_to_kw` method. - """ - multivalue = False - for (i, arg) in enumerate(self.args()): - assert not multivalue - if len(values) > i: - if arg.multivalue: - multivalue = True - if len(values) == i + 1 and type(values[i]) in (list, tuple): - yield (arg.name, values[i]) - else: - yield (arg.name, values[i:]) - else: - yield (arg.name, values[i]) - else: - break - def args_options_2_params(self, *args, **options): """ Merge (args, options) into params. @@ -182,9 +144,9 @@ class Command(plugable.Plugin): if name in options: yield (name, options[name]) - def params_2_args_options(self, params): + def params_2_args_options(self, **params): """ - Split params into (args, kw). + Split params into (args, options). """ args = tuple(params.get(name, None) for name in self.args) options = dict(self.__params_2_options(params)) diff --git a/tests/test_ipalib/test_frontend.py b/tests/test_ipalib/test_frontend.py index 25e225135..0030a41e5 100644 --- a/tests/test_ipalib/test_frontend.py +++ b/tests/test_ipalib/test_frontend.py @@ -298,37 +298,6 @@ class test_Command(ClassChecker): e = raises(NotImplementedError, o.execute) assert str(e) == 'Command.execute()' - def test_args_to_kw(self): - """ - Test the `ipalib.frontend.Command.args_to_kw` method. - """ - assert 'args_to_kw' in self.cls.__public__ # Public - o = self.get_instance(args=('one', 'two?')) - assert o.args_to_kw(1) == dict(one=1) - assert o.args_to_kw(1, 2) == dict(one=1, two=2) - - o = self.get_instance(args=('one', 'two*')) - assert o.args_to_kw(1) == dict(one=1) - assert o.args_to_kw(1, 2) == dict(one=1, two=(2,)) - assert o.args_to_kw(1, 2, 3) == dict(one=1, two=(2, 3)) - - o = self.get_instance(args=('one', 'two+')) - assert o.args_to_kw(1) == dict(one=1) - assert o.args_to_kw(1, 2) == dict(one=1, two=(2,)) - assert o.args_to_kw(1, 2, 3) == dict(one=1, two=(2, 3)) - - o = self.get_instance() - e = raises(errors.ArgumentError, o.args_to_kw, 1) - assert str(e) == 'example takes no arguments' - - o = self.get_instance(args=('one?',)) - e = raises(errors.ArgumentError, o.args_to_kw, 1, 2) - assert str(e) == 'example takes at most 1 argument' - - o = self.get_instance(args=('one', 'two?')) - e = raises(errors.ArgumentError, o.args_to_kw, 1, 2, 3) - assert str(e) == 'example takes at most 2 arguments' - def test_args_options_2_params(self): """ Test the `ipalib.frontend.Command.args_options_2_params` method. @@ -382,11 +351,10 @@ class test_Command(ClassChecker): """ assert 'params_2_args_options' in self.cls.__public__ # Public o = self.get_instance(args=['one'], options=['two']) - assert o.params_2_args_options({}) == ((None,), {}) - assert o.params_2_args_options(dict(one=1)) == ((1,), {}) - assert o.params_2_args_options(dict(two=2)) == ((None,), dict(two=2)) - assert o.params_2_args_options(dict(two=2, one=1)) == \ - ((1,), dict(two=2)) + assert o.params_2_args_options() == ((None,), {}) + assert o.params_2_args_options(one=1) == ((1,), {}) + assert o.params_2_args_options(two=2) == ((None,), dict(two=2)) + assert o.params_2_args_options(two=2, one=1) == ((1,), dict(two=2)) def test_run(self): """