changeset 7388:5751631246de

dispatch: generalize signature checking for extension command wrapping
author Matt Mackall <mpm@selenic.com>
date Tue, 18 Nov 2008 16:02:14 -0600
parents 7e9a15fa6c8f
children 040484030491
files mercurial/dispatch.py mercurial/extensions.py mercurial/util.py
diffstat 3 files changed, 23 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/dispatch.py	Tue Nov 18 15:35:34 2008 -0600
+++ b/mercurial/dispatch.py	Tue Nov 18 16:02:14 2008 -0600
@@ -7,7 +7,7 @@
 
 from i18n import _
 from repo import RepoError
-import os, sys, atexit, signal, pdb, traceback, socket, errno, shlex, time
+import os, sys, atexit, signal, pdb, socket, errno, shlex, time
 import util, commands, hg, lock, fancyopts, revlog, version, extensions, hook
 import cmdutil
 import ui as _ui
@@ -356,9 +356,9 @@
                     raise RepoError(_("There is no Mercurial repository here"
                                       " (.hg not found)"))
                 raise
-        d = lambda: func(ui, repo, *args, **cmdoptions)
-    else:
-        d = lambda: func(ui, *args, **cmdoptions)
+        args.insert(0, repo)
+
+    d = lambda: util.checksignature(func)(ui, *args, **cmdoptions)
 
     # run pre-hook, and abort if it fails
     ret = hook.hook(lui, repo, "pre-%s" % cmd, False, args=" ".join(fullargs))
@@ -374,11 +374,7 @@
     def checkargs():
         try:
             return cmdfunc()
-        except TypeError:
-            # was this an argument error?
-            tb = traceback.extract_tb(sys.exc_info()[2])
-            if len(tb) != 2: # no
-                raise
+        except util.SignatureError:
             raise ParseError(cmd, _("invalid arguments"))
 
     if options['profile']:
--- a/mercurial/extensions.py	Tue Nov 18 15:35:34 2008 -0600
+++ b/mercurial/extensions.py	Tue Nov 18 16:02:14 2008 -0600
@@ -96,7 +96,8 @@
 
     origfn = entry[0]
     def wrap(*args, **kwargs):
-        return wrapper(origfn, *args, **kwargs)
+        return util.checksignature(wrapper)(
+            util.checksignature(origfn), *args, **kwargs)
 
     wrap.__doc__ = getattr(origfn, '__doc__')
     wrap.__module__ = getattr(origfn, '__module__')
--- a/mercurial/util.py	Tue Nov 18 15:35:34 2008 -0600
+++ b/mercurial/util.py	Tue Nov 18 16:02:14 2008 -0600
@@ -13,7 +13,7 @@
 """
 
 from i18n import _
-import cStringIO, errno, getpass, re, shutil, sys, tempfile
+import cStringIO, errno, getpass, re, shutil, sys, tempfile, traceback
 import os, stat, threading, time, calendar, ConfigParser, locale, glob, osutil
 import imp
 
@@ -671,6 +671,21 @@
         if cwd is not None and oldcwd != cwd:
             os.chdir(oldcwd)
 
+class SignatureError:
+    pass
+
+def checksignature(func):
+    '''wrap a function with code to check for calling errors'''
+    def check(*args, **kwargs):
+        try:
+            return func(*args, **kwargs)
+        except TypeError:
+            if len(traceback.extract_tb(sys.exc_info()[2])) == 1:
+                raise SignatureError
+            raise
+
+    return check
+
 # os.path.lexists is not available on python2.3
 def lexists(filename):
     "test whether a file with this name exists. does not follow symlinks"