Mercurial > public > mercurial-scm > hg
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''' |