commander: specific error for mismatched args
2 files changed, 23 insertions(+), 2 deletions(-)

M test/test_cli_commands.py
M vanity/commander.py
M test/test_cli_commands.py +9 -1
@@ 216,7 216,6 @@ class TestCliCommands(unittest.TestCase)
             commander.main(GOPT_A, CMDTABLE_A, arguments))
 
     def test_main_dispatch_special(self):
-        sys.stderr = StringIO.StringIO()
         try:
             commander.main(GOPT_A, CMDTABLE_A, 'foo -h'.split())
             caught = False

          
@@ 236,6 235,15 @@ class TestCliCommands(unittest.TestCase)
             caught = True
         self.assertTrue(caught)
 
+    def test_main_dispatch_badargs(self):
+        try:
+            commander.main(GOPT_A, CMDTABLE_A, 'foo x y z'.split())
+            caught = False
+        except:
+            caught = True
+        self.assertTrue(caught)
+        
+
 
             
 class Capture(list):

          
M vanity/commander.py +14 -1
@@ 19,6 19,7 @@ XXX
 
 from vanity import cli
 import sys
+import traceback
 
 
 class InvalidCommand(cli.CliError):

          
@@ 49,6 50,13 @@ class HelpWanted(cli.CliError):
         self.args = args
 
 
+class InvalidArguments(cli.CliError):
+    """The user failed to give correct number of args"""
+    def __init__(self, name):
+        cli.CliError.__init__(self,
+            '%s: unexpected number of arguments' % name)
+
+
 def main(globalopts, cmdtable, arguments, generichelp=None):
     """Launch a subcommand based on the given arguments, automatically
     handling help and cli parsing errors. Will return the

          
@@ 207,7 215,12 @@ class Command(object):
         self.strict = strict
 
     def __call__(self, opts, args):
-        return self.target(*args, **opts)
+        try:
+            return self.target(*args, **opts)
+        except TypeError, err:
+            if len(traceback.extract_tb(sys.exc_info()[2])) == 1:
+                raise InvalidArguments(self.name)
+            raise
 
     def aliaslist(self):
         """Return a list of command aliases.