Author: janne.t.harkonen
Date: Wed Nov 26 03:43:54 2008
New Revision: 1132
Modified:
trunk/src/robot/utils/argumentparser.py
trunk/utest/utils/test_argumentparser.py
Log:
Argumenparser can be given arg limits
Modified: trunk/src/robot/utils/argumentparser.py
==============================================================================
--- trunk/src/robot/utils/argumentparser.py (original)
+++ trunk/src/robot/utils/argumentparser.py Wed Nov 26 03:43:54 2008
@@ -22,7 +22,7 @@
from robot.errors import DataError, Information, FrameworkError
-from misc import seq2str, plural_or_not
+from misc import plural_or_not
from robottypes import is_list, is_boolean
from text import wrap
@@ -48,12 +48,12 @@
_usage_line_re = re.compile('''
^usage:.*
- \[options\]\s+
- (.*) # arguments (group 1)
+ \[options\]\s*
+ (.*?) # arguments (group 1)
\s*$
''', re.VERBOSE | re.IGNORECASE)
- def __init__(self, usage, version=None):
+ def __init__(self, usage, version=None, arg_limits=None):
"""Available options and tool name are read from the usage.
Tool name is got from the first row of the usage. It is either the
@@ -66,6 +66,7 @@
self._usage = usage
self._name = usage.splitlines()[0].split(' -- ')[0].strip()
self._version = version
+ self._arg_limits = arg_limits
self._short_opts = ''
self._long_opts = []
self._multi_opts = []
@@ -148,18 +149,19 @@
return self._process_opts(opts), self._glob_args(args)
def _check_args(self, args):
- if len(args) == len(self._expected_args):
- return
- elif len(args) < len(self._expected_args):
- msg = 'Required argument%s missing.' %
plural_or_not(self._expected_args)
- elif self._expected_args and self._expected_args[-1].endswith('s'):
+ if not self._arg_limits:
+ raise FrameworkError('No argument information specified.')
+ minargs, maxargs = self._arg_limits
+ if minargs <= len(args) <= maxargs:
return
+ minend = plural_or_not(minargs)
+ if minargs == maxargs:
+ exptxt = "%d argument%s" % (minargs, minend)
+ elif maxargs != sys.maxint:
+ exptxt = "%d to %d arguments" % (minargs, maxargs)
else:
- msg = 'Too many arguments.'
- msg += ' Expected %s' % seq2str(self._expected_args)
- if args:
- msg += ' but got %s' % seq2str(args)
- raise DataError(msg + '.')
+ exptxt = "at least %d argument%s" % (minargs, minend)
+ raise DataError("Expected %s, got %d." % (exptxt, len(args)))
def _unescape_opts_and_args(self, opts, args, escape_opt):
try:
@@ -271,15 +273,23 @@
def _parse_usage(self, usage):
for line in usage.splitlines():
- res = self._opt_line_re.match(line)
- if res:
- self._parse_opt_line(res)
- continue
- res = self._usage_line_re.match(line)
- if res:
- self._expected_args = res.group(1).split()
+ if not self._parse_opt_line(line) and not self._arg_limits:
+ self._parse_usage_line(line)
+
+ def _parse_usage_line(self, line):
+ res = self._usage_line_re.match(line)
+ if res:
+ args = res.group(1).split()
+ if not args:
+ self._arg_limits = (0, 0)
+ else:
+ maxargs = args[-1].endswith('s') and sys.maxint or
len(args)
+ self._arg_limits = (len(args), maxargs)
- def _parse_opt_line(self, res):
+ def _parse_opt_line(self, line):
+ res = self._opt_line_re.match(line)
+ if not res:
+ return False
long_opt = res.group(3).lower()
if long_opt in self._names:
self._raise_option_multiple_times_in_usage('--' + long_opt)
@@ -300,6 +310,7 @@
self._toggle_opts.append(long_opt)
self._long_opts.append(long_opt)
self._short_opts += (''.join(short_opts))
+ return True
def _get_pythonpath(self, paths):
if not is_list(paths):
Modified: trunk/utest/utils/test_argumentparser.py
==============================================================================
--- trunk/utest/utils/test_argumentparser.py (original)
+++ trunk/utest/utils/test_argumentparser.py Wed Nov 26 03:43:54 2008
@@ -156,7 +156,24 @@
ap.parse_args(['one_is_ok'], check_args=True)
ap.parse_args(['two', 'ok'], check_args=True)
ap.parse_args(['this', 'should', 'also', 'work', '!'],
check_args=True)
- assert_raises(DataError, ap._check_args, [])
+ assert_raises_with_msg(DataError, "Expected at least 1 argument,
got 0.",
+ ap._check_args, [])
+
+ def test_arg_limits_to_constructor(self):
+ ap = ArgumentParser('usage: test.py [options] args',
arg_limits=(2,4))
+ assert_raises_with_msg(DataError, "Expected 2 to 4 arguments, got
1.",
+ ap._check_args, ['one is not enough'])
+
+ def test_reading_args_from_usage_when_it_has_just_options(self):
+ ap = ArgumentParser('usage: test.py [options]')
+ ap.parse_args([], check_args=True)
+ assert_raises_with_msg(DataError, "Expected 0 arguments, got 2.",
+ ap._check_args, ['1', '2'])
+
+ def test_check_args_fails_when_no_args_specified(self):
+ assert_raises(FrameworkError, ArgumentParser('test').parse_args,
+ [], check_args=True)
+
def test_unescape_options(self):
cli = '--escape quot:Q -E space:SP -E lt:LT -E gt:GT ' \