comparison mercurial/util.py @ 31315:78ac7061f840

util: add debugstacktrace depth limit Useful when you don't care about the start of the stack, but only want to see the last entries.
author Mads Kiilerich <madski@unity3d.com>
date Wed, 14 Jan 2015 01:15:26 +0100
parents 7c877cbf30d6
children a9a28ca17615
comparison
equal deleted inserted replaced
31314:7c877cbf30d6 31315:78ac7061f840
2839 results = [] 2839 results = []
2840 for source, hook in self._hooks: 2840 for source, hook in self._hooks:
2841 results.append(hook(*args)) 2841 results.append(hook(*args))
2842 return results 2842 return results
2843 2843
2844 def getstackframes(skip=0, line=' %-*s in %s\n', fileline='%s:%s'): 2844 def getstackframes(skip=0, line=' %-*s in %s\n', fileline='%s:%s', depth=0):
2845 '''Yields lines for a nicely formatted stacktrace. 2845 '''Yields lines for a nicely formatted stacktrace.
2846 Skips the 'skip' last entries. 2846 Skips the 'skip' last entries, then return the last 'depth' entries.
2847 Each file+linenumber is formatted according to fileline. 2847 Each file+linenumber is formatted according to fileline.
2848 Each line is formatted according to line. 2848 Each line is formatted according to line.
2849 If line is None, it yields: 2849 If line is None, it yields:
2850 length of longest filepath+line number, 2850 length of longest filepath+line number,
2851 filepath+linenumber, 2851 filepath+linenumber,
2852 function 2852 function
2853 2853
2854 Not be used in production code but very convenient while developing. 2854 Not be used in production code but very convenient while developing.
2855 ''' 2855 '''
2856 entries = [(fileline % (fn, ln), func) 2856 entries = [(fileline % (fn, ln), func)
2857 for fn, ln, func, _text in traceback.extract_stack()[:-skip - 1]] 2857 for fn, ln, func, _text in traceback.extract_stack()[:-skip - 1]
2858 ][-depth:]
2858 if entries: 2859 if entries:
2859 fnmax = max(len(entry[0]) for entry in entries) 2860 fnmax = max(len(entry[0]) for entry in entries)
2860 for fnln, func in entries: 2861 for fnln, func in entries:
2861 if line is None: 2862 if line is None:
2862 yield (fnmax, fnln, func) 2863 yield (fnmax, fnln, func)
2863 else: 2864 else:
2864 yield line % (fnmax, fnln, func) 2865 yield line % (fnmax, fnln, func)
2865 2866
2866 def debugstacktrace(msg='stacktrace', skip=0, f=stderr, otherf=stdout): 2867 def debugstacktrace(msg='stacktrace', skip=0,
2868 f=stderr, otherf=stdout, depth=0):
2867 '''Writes a message to f (stderr) with a nicely formatted stacktrace. 2869 '''Writes a message to f (stderr) with a nicely formatted stacktrace.
2868 Skips the 'skip' last entries. By default it will flush stdout first. 2870 Skips the 'skip' entries closest to the call, then show 'depth' entries.
2871 By default it will flush stdout first.
2869 It can be used everywhere and intentionally does not require an ui object. 2872 It can be used everywhere and intentionally does not require an ui object.
2870 Not be used in production code but very convenient while developing. 2873 Not be used in production code but very convenient while developing.
2871 ''' 2874 '''
2872 if otherf: 2875 if otherf:
2873 otherf.flush() 2876 otherf.flush()
2874 f.write('%s at:\n' % msg.rstrip()) 2877 f.write('%s at:\n' % msg.rstrip())
2875 for line in getstackframes(skip + 1): 2878 for line in getstackframes(skip + 1, depth=depth):
2876 f.write(line) 2879 f.write(line)
2877 f.flush() 2880 f.flush()
2878 2881
2879 class dirs(object): 2882 class dirs(object):
2880 '''a multiset of directory names from a dirstate or manifest''' 2883 '''a multiset of directory names from a dirstate or manifest'''