1# 2# Gramps - a GTK+/GNOME based genealogy program 3# 4# Copyright (C) 2000-2007 Donald N. Allingham 5# Copyright (C) 2009 Gary Burton 6# Copyright (C) 2011 Tim G L Lyons 7# 8# This program is free software; you can redistribute it and/or modify 9# it under the terms of the GNU General Public License as published by 10# the Free Software Foundation; either version 2 of the License, or 11# (at your option) any later version. 12# 13# This program is distributed in the hope that it will be useful, 14# but WITHOUT ANY WARRANTY; without even the implied warranty of 15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16# GNU General Public License for more details. 17# 18# You should have received a copy of the GNU General Public License 19# along with this program; if not, write to the Free Software 20# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21# 22 23""" 24Debugging utilities 25""" 26import cProfile 27import pstats 28import sys 29 30 31#------------------------------------------------------------------------- 32# 33# Debugging utilities 34# 35#------------------------------------------------------------------------- 36def profile(func, *args, **kwargs): 37 38 prf = cProfile.Profile() 39 print("Start") 40 r = prf.runcall(func, *args, **kwargs) 41 print("Finished") 42 print("Loading profile") 43 stats = pstats.Stats(prf, stream=sys.stdout) 44 print("done") 45 stats.strip_dirs() 46 stats.sort_stats('time', 'calls') 47 stats.print_stats(100) 48 stats.print_callers(100) 49 return r 50 51def format_exception(tb_type=None, tb_value=None, tb=None): 52 """ 53 Get the usual traceback information, followed by a listing of all the 54 local variables in each frame. 55 Based on: 56 code.activestate.com/recipes/52215-get-more-information-from-tracebacks 57 """ 58 import sys 59 import traceback 60 if tb_type is None: 61 tb_type = sys.exc_type 62 if tb_value is None: 63 tb_value = sys.exc_value 64 if tb is None: 65 tb = sys.exc_info()[2] 66 retval = traceback.format_exception(tb_type, tb_value, tb) + ["\n"] 67 while tb.tb_next: 68 tb = tb.tb_next 69 stack = [] 70 f = tb.tb_frame 71 while f: 72 stack.append(f) 73 f = f.f_back 74 stack.reverse() 75 retval.append("Local variables (most recent frame last):\n") 76 for frame in stack: 77 retval.append(" Frame %s, File \"%s\", line %s:\n" % (frame.f_code.co_name, 78 frame.f_code.co_filename, 79 frame.f_lineno)) 80 for key, value in frame.f_locals.items(): 81 if key.startswith("__"): 82 continue 83 #We have to be careful not to cause a new error in our error 84 #handler! Calling str() on an unknown object could cause an 85 #error we don't want. 86 try: 87 line = " %s = %s\n" % (key, str(value)) 88 except: 89 line = " %s = %s\n" % (key, "<ERROR PRINTING VALUE>") 90 retval.append(line) 91 return retval 92