1987 def __call__(self, *args): |
1987 def __call__(self, *args): |
1988 self._hooks.sort(key=lambda x: x[0]) |
1988 self._hooks.sort(key=lambda x: x[0]) |
1989 for source, hook in self._hooks: |
1989 for source, hook in self._hooks: |
1990 hook(*args) |
1990 hook(*args) |
1991 |
1991 |
1992 def debugstacktrace(msg='stacktrace', skip=0, f=sys.stderr): |
1992 def debugstacktrace(msg='stacktrace', skip=0, f=sys.stderr, otherf=sys.stdout): |
1993 '''Writes a message to f (stderr) with a nicely formatted stacktrace. |
1993 '''Writes a message to f (stderr) with a nicely formatted stacktrace. |
1994 Skips the 'skip' last entries. |
1994 Skips the 'skip' last entries. By default it will flush stdout first. |
1995 It can be used everywhere and do intentionally not require an ui object. |
1995 It can be used everywhere and do intentionally not require an ui object. |
1996 Not be used in production code but very convenient while developing. |
1996 Not be used in production code but very convenient while developing. |
1997 ''' |
1997 ''' |
|
1998 if otherf: |
|
1999 otherf.flush() |
1998 f.write('%s at:\n' % msg) |
2000 f.write('%s at:\n' % msg) |
1999 entries = [('%s:%s' % (fn, ln), func) |
2001 entries = [('%s:%s' % (fn, ln), func) |
2000 for fn, ln, func, _text in traceback.extract_stack()[:-skip - 1]] |
2002 for fn, ln, func, _text in traceback.extract_stack()[:-skip - 1]] |
2001 if entries: |
2003 if entries: |
2002 fnmax = max(len(entry[0]) for entry in entries) |
2004 fnmax = max(len(entry[0]) for entry in entries) |
2003 for fnln, func in entries: |
2005 for fnln, func in entries: |
2004 f.write(' %-*s in %s\n' % (fnmax, fnln, func)) |
2006 f.write(' %-*s in %s\n' % (fnmax, fnln, func)) |
|
2007 f.flush() |
2005 |
2008 |
2006 # convenient shortcut |
2009 # convenient shortcut |
2007 dst = debugstacktrace |
2010 dst = debugstacktrace |