changeset 2546:56dbfbde79fe

better error checking in parameter parser, no more TypeError
author Johannes Berg <johannes AT sipsolutions DOT net>
date Mon, 23 Jul 2007 19:37:36 +0200
parents 3ef21e54f940
children c2ef5800253f
files MoinMoin/_tests/test_wikiutil.py MoinMoin/macro/__init__.py MoinMoin/wikiutil.py
diffstat 3 files changed, 35 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/MoinMoin/_tests/test_wikiutil.py	Mon Jul 23 19:37:10 2007 +0200
+++ b/MoinMoin/_tests/test_wikiutil.py	Mon Jul 23 19:37:36 2007 +0200
@@ -539,7 +539,7 @@
                        self._test_invoke_int_None, u'""')
         py.test.raises(ValueError, ief, self.request,
                        self._test_invoke_int_None, u'i=""')
-        py.test.raises(TypeError, ief, self.request,
+        py.test.raises(ValueError, ief, self.request,
                        _test_invoke_int_fixed, u'a=7', [7, 8])
         ief(self.request, _test_invoke_int_fixed, u'i=1', [7, 8])
         py.test.raises(ValueError, ief, self.request,
--- a/MoinMoin/macro/__init__.py	Mon Jul 23 19:37:10 2007 +0200
+++ b/MoinMoin/macro/__init__.py	Mon Jul 23 19:37:36 2007 +0200
@@ -101,7 +101,7 @@
 
     def format_error(self, err):
         """ format an error object for output instead of normal macro output """
-        return self.formatter.text(u'[[%s: %s]]' % (self.name, unicode(err)))
+        return self.formatter.text(u'[[%s: %s]]' % (self.name, err.args[0]))
 
     def execute(self, macro_name, args):
         """ Get and execute a macro
--- a/MoinMoin/wikiutil.py	Mon Jul 23 19:37:10 2007 +0200
+++ b/MoinMoin/wikiutil.py	Mon Jul 23 19:37:36 2007 +0200
@@ -1533,11 +1533,12 @@
 
     assert isinstance(fixed_args, list) or isinstance(fixed_args, tuple)
 
+    _ = request.getText
+
     if args:
         assert isinstance(args, unicode)
 
-        positional, keyword, trailing = \
-            parse_quoted_separated(args)
+        positional, keyword, trailing = parse_quoted_separated(args)
 
         kwargs = {}
         nonascii = {}
@@ -1583,30 +1584,48 @@
     defstart = argc - len(defaultlist)
 
     defaults = {}
+    # reverse to be able to pop() things off
+    positional.reverse()
+    allow_non_ascii_kw = False
+    allow_trailing = False
     # convert all arguments to keyword arguments,
     # fill all arguments that weren't given with None
     for idx in range(argc):
         argname = argnames[idx]
-        if argname in ['_non_ascii_kwargs', '_trailing_args']:
+        if argname == '_non_ascii_kwargs':
+            allow_non_ascii_kw = True
             continue
-        if idx < len(positional):
-            kwargs[argname] = positional[idx]
+        if argname == '_trailing_args':
+            allow_trailing = True
+            continue
+        if positional:
+            kwargs[argname] = positional.pop()
         if not argname in kwargs:
             kwargs[argname] = None
         if idx >= defstart:
             defaults[argname] = defaultlist[idx - defstart]
 
+    if positional:
+        raise ValueError(_('Too many arguments'))
+    if '_trailing_args' in kwargs and not allow_trailing:
+        raise ValueError(_('Cannot have arguments without name following'
+                           ' named arguments'))
+    if '_non_ascii_kwargs' in kwargs and not allow_non_ascii_kw:
+        raise ValueError(_(u'No argument named "%s"') % (
+            kwargs['_non_ascii_kwargs'].keys()[0]))
+
     # type-convert all keyword arguments to the type
     # that the default value indicates
-    for argname in defaults:
-        default = defaults[argname]
-
-        # the value of 'argname' from kwargs will be put into the
-        # macro's 'argname' argument, so convert that giving the
-        # name to the converter so the user is told which argument
-        # went wrong (if it does)
-        kwargs[argname] = _convert_arg(request, kwargs[argname],
-                                       default, argname)
+    for argname in kwargs:
+        if not varkw and not argname in argnames:
+            raise ValueError(_('No argument named "%s"') % argname)
+        if argname in defaults:
+            # the value of 'argname' from kwargs will be put into the
+            # macro's 'argname' argument, so convert that giving the
+            # name to the converter so the user is told which argument
+            # went wrong (if it does)
+            kwargs[argname] = _convert_arg(request, kwargs[argname],
+                                           defaults[argname], argname)
 
     return function(*fixed_args, **kwargs)