Let's play it safe when restoring state in select_node.
[straw.git] / straw / error.py
blobcb528d0a18531875881890d25b9cde804df23d73
1 """ error.py
3 Module for logging errors
4 """
5 __copyright__ = "Copyright (c) 2002-2005 Free Software Foundation, Inc."
6 __license__ = """ GNU General Public License
8 This program is free software; you can redistribute it and/or modify it under the
9 terms of the GNU General Public License as published by the Free Software
10 Foundation; either version 2 of the License, or (at your option) any later
11 version.
13 This program is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License along with
18 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
19 Place - Suite 330, Boston, MA 02111-1307, USA. """
21 from StringIO import StringIO
22 import logging
23 import pprint
24 import sys
25 import traceback
27 stream = sys.stderr
29 def setup_log():
30 logging.basicConfig(level=logging.DEBUG,
31 format='%(asctime)s %(levelname)-8s %(message)s',
32 filename='straw.log',
33 filemode='w')
35 console = logging.StreamHandler()
36 console.setLevel(logging.DEBUG)
37 formatter = logging.Formatter('%(asctime)s %(levelname)-8s %(message)s')
38 console.setFormatter(formatter)
39 logging.getLogger('').addHandler(console)
41 def get_logger():
42 # TODO: introduce hierarchical loggers
43 return logging.getLogger("")
45 def debug(msg, *args, **kwargs):
46 logging.debug(msg)
48 def log(*args):
49 caller = traceback.extract_stack()[-2]
50 _log(caller, *args)
52 def _log(caller = None, *args):
53 if caller is None:
54 caller = traceback.extract_stack()[-2]
55 try:
56 cf = caller[0][caller[0].rindex("/")+1:]
57 except:
58 cf = caller[0]
59 stream.write("%s:%d:%s: " % (cf, caller[1], caller[2]))
60 for a in args:
61 if type(a) is not type(''):
62 a = repr(a)
63 stream.write(a)
64 stream.write("\n")
66 def logtb(*args):
67 _log(traceback.extract_stack()[-2], *args)
68 l = traceback.format_list(traceback.extract_stack()[:-1])
69 for e in l:
70 stream.write(e)
72 def logparam(locals, *vars):
73 logargs = []
74 for v in vars:
75 logargs.append(v + ": " + str(locals[v]))
76 _log(traceback.extract_stack()[-2], ", ".join(logargs))
78 def logpparam(locals, *vars):
79 logargs = []
80 for v in vars:
81 sio = StringIO()
82 pprint.pprint(locals[v], sio)
83 logargs.append(v + ": " + sio.getvalue())
84 sio.close()
85 _log(traceback.extract_stack()[-2], "".join(logargs))
88 depth = 0
89 def incr_depth():
90 global depth
91 depth += 1
92 def decr_depth():
93 global depth
94 depth -= 1
95 def get_indent(): return " " * depth
97 def debug_around(f):
98 caller = traceback.extract_stack()[-2]
100 def f2(*args, **kwargs):
101 def maybe_str(o):
102 if isinstance(o, str):
103 return repr(o)
104 return str(o)
105 indent = get_indent()
106 _log(caller, "%sEntering " % indent, f.__name__)
107 argstr = ", ".join([maybe_str(a) for a in args])
108 if len(kwargs) > 0:
109 argstr += ", " + ", ".join(
110 ["%s: %s" % (maybe_str(k), maybe_str(v))
111 for k, v in kwargs.items()])
112 _log(caller, "%sArgs: (" % indent, argstr, ")")
113 incr_depth()
114 r = None
115 try:
116 r = f(*args, **kwargs)
117 finally:
118 decr_depth()
119 _log(caller, "%sReturning %s from %s" % (
120 indent, str(r), f.__name__))
121 return r
124 return f2
126 # Originally by Bryn Keller
127 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52215
128 def log_exc(message):
130 Print the usual traceback information, followed by a listing of all the
131 local variables in each frame.
133 _log(traceback.extract_stack()[-2], message)
134 tb = sys.exc_info()[2]
135 while 1:
136 if not tb.tb_next:
137 break
138 tb = tb.tb_next
139 stack = []
140 f = tb.tb_frame
141 while f:
142 stack.append(f)
143 f = f.f_back
144 stack.reverse()
145 traceback.print_exc()
146 print >>stream, "Locals by frame, innermost last"
147 for frame in stack:
148 print >>stream
149 print >>stream, "Frame %s in %s at line %s" % (
150 frame.f_code.co_name, frame.f_code.co_filename,
151 frame.f_lineno)
152 for key, value in frame.f_locals.items():
153 print >>stream, "\t%20s = " % key,
154 #We have to be careful not to cause a new error in our error
155 #printer! Calling str() on an unknown object could cause an
156 #error we don't want.
157 try:
158 print >>stream, value
159 except:
160 print >>stream, "<ERROR WHILE PRINTING VALUE>"