From: W. Trevor King Date: Wed, 12 May 2010 12:05:48 +0000 (-0400) Subject: Added Argument.count handling to hooke.ui.commandline. X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=c10464cc037e7e29d54b295b4648ec548b95ab36;p=hooke.git Added Argument.count handling to hooke.ui.commandline. --- diff --git a/hooke/ui/commandline.py b/hooke/ui/commandline.py index 5198f8f..0c08d39 100644 --- a/hooke/ui/commandline.py +++ b/hooke/ui/commandline.py @@ -38,6 +38,14 @@ class CommandLineParser (optparse.OptionParser): self.command_opts.append(a) else: self.command_args.append(a) + infinite_counters = [a for a in self.command_args if a.count == -1] + assert len(infinite_counters) <= 1, \ + 'Multiple infinite counts for %s: %s\nNeed a better CommandLineParser implementation.' \ + % (command.name, ', '.join([a.name for a in infinite_counters])) + if len(infinite_counters) == 1: # move the big counter to the end. + infinite_counter = infinite_counters[0] + self.command_args.remove(infinite_counter) + self.command_args.append(infinite_counter) def exit(self, status=0, msg=None): """Override :meth:`optparse.OptionParser.exit` which calls @@ -91,20 +99,53 @@ class DoCommand (CommandMethod): def _parse_args(self, args): argv = shlex.split(args, comments=True, posix=True) options,args = self.parser.parse_args(argv) - if len(args) != len(self.parser.command_args): - raise optparse.OptParseError('%d arguments given, but %s takes %d' - % (len(args), - self.name_fn(self.command.name), - len(self.parser.command_args))) + self._check_argument_length_bounds(args) params = {} for argument in self.parser.command_opts: value = getattr(options, self.name_fn(argument.name)) if value != Default: params[argument.name] = value - for i,argument in enumerate(self.parser.command_args): - params[argument.name] = args[i] + arg_index = 0 + for argument in self.parser.command_args: + if argument.count == 1: + params[argument.name] = args[arg_index] + elif argument.count > 1: + params[argument.name] = \ + args[arg_index:arg_index+argument.count] + else: # argument.count == -1: + params[argument.name] = args[arg_index:] + arg_index += argument.count return params + def _check_argument_length_bounds(self, arguments): + """Check that there are an appropriate number of arguments in + `args`. + + If not, raise optparse.OptParseError(). + """ + min_args = 0 + max_args = -1 + for argument in self.parser.command_args: + if argument.optional == False and argument.count > 0: + min_args += argument.count + if max_args >= 0: # otherwise already infinite + if argument.count == -1: + max_args = -1 + else: + max_args += argument.count + if len(arguments) < min_args \ + or (max_args >= 0 and len(arguments) > max_args): + if min_args == max_args: + target_string = str(min_args) + elif max_args == -1: + target_string = 'more than %d' % min_args + else: + target_string = '%d to %d' % (min_args, max_args) + raise optparse.OptParseError( + '%d arguments given, but %s takes %s' + % (len(arguments), self.name_fn(self.command.name), + target_string)) + def _boolean_request(self, msg): if msg.default == True: yn = ' [Y/n] '