comparison mercurial/util.py @ 20542:be27652675ce

util: debugstacktrace, flush before and after writing Close another stream (default stdout, which often is buffered) before writing to the primary stream (default stderr, which often is unbuffered). The primary stream is also flushed after writing (in case it is buffered). This fixes non-deterministic output order, especially on windows.
author Mads Kiilerich <madski@unity3d.com>
date Thu, 20 Feb 2014 02:38:36 +0100
parents 0889585b44f1
children 0916f829eb8d
comparison
equal deleted inserted replaced
20541:44dcca9be1d5 20542:be27652675ce
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