import sys import types def call_with_sig_error(callable, *args, **kw): try: return callable(*args, **kw) except: exc_info = sys.exc_info() exc_info = annotate_signature_error(exc_info, callable, args, kw) raise exc_info[0], exc_info[1], exc_info[2] def annotate_signature_error(exc_info, callable, args, kwargs): if (exc_info[0] != TypeError or str(exc_info[1]).find('argument') == -1): return exc_info import inspect argspec = inspect.formatargspec(*inspect.getargspec(callable)) args = ', '.join(map(repr, args)) if kwargs and args: args += ', ' args += ', '.join(['%s=%r' % (n, v) for n, v in kwargs.items()]) gotspec = '(%s)' % args msg = '%s; got %s, wanted %s' % (exc_info[1], gotspec, argspec) exc_info[1].args = (msg,) return exc_info