# HG changeset patch # User Mads Kiilerich # Date 2014-02-20 01:38:36 # Node ID be27652675ceca35e4b413ef1b35aac562a876f5 # Parent 44dcca9be1d5c45aa802abdcb5ebf4c2f24e64f4 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. diff --git a/mercurial/util.py b/mercurial/util.py --- a/mercurial/util.py +++ b/mercurial/util.py @@ -1989,12 +1989,14 @@ class hooks(object): for source, hook in self._hooks: hook(*args) -def debugstacktrace(msg='stacktrace', skip=0, f=sys.stderr): +def debugstacktrace(msg='stacktrace', skip=0, f=sys.stderr, otherf=sys.stdout): '''Writes a message to f (stderr) with a nicely formatted stacktrace. - Skips the 'skip' last entries. + Skips the 'skip' last entries. By default it will flush stdout first. It can be used everywhere and do intentionally not require an ui object. Not be used in production code but very convenient while developing. ''' + if otherf: + otherf.flush() f.write('%s at:\n' % msg) entries = [('%s:%s' % (fn, ln), func) for fn, ln, func, _text in traceback.extract_stack()[:-skip - 1]] @@ -2002,6 +2004,7 @@ def debugstacktrace(msg='stacktrace', sk fnmax = max(len(entry[0]) for entry in entries) for fnln, func in entries: f.write(' %-*s in %s\n' % (fnmax, fnln, func)) + f.flush() # convenient shortcut dst = debugstacktrace