]>
git.saurik.com Git - wxWidgets.git/blob - wxPython/wx/tools/dbg.py
1 #----------------------------------------------------------------------------
5 # Email: wsadkin@nameconnector.com
7 # Copyright: (c) 2002 by Will Sadkin, 2002
8 # License: wxWindows license
9 #----------------------------------------------------------------------------
12 This module provides a useful debugging framework that supports
13 showing nesting of function calls and allows a program to contain
14 lots of debugging print statements that can easily be turned on
15 or off to debug the code. It also supports the ability to
16 have each function indent the debugging statements contained
17 within it, including those of any other function called within
18 its scope, thus allowing you to see in what order functions are
19 being called, and from where.
21 This capability is particularly useful in wxPython applications,
22 where exactly events occur that cause functions to be called is
23 not entirely clear, and because wxPython programs can't be run
24 from inside other debugging environments that have their own
27 This module defines a Logger class, responsible for managing
28 debugging output. Each Logger instance can be given a name
29 at construction; if this is done, '<name>:' will precede each
30 logging output made by that Logger instance.
32 The log() function this class provides takes a set of positional
33 arguments that are printed in order if debugging is enabled
34 (just like print does), followed by a set of keyword arguments
35 that control the behavior of the log() function itself on subsequent
36 calls. The current keyword arguments are:
39 When set to a value of 1, this increments the current
40 indentation level, causing all subsequent dbg() outputs to be
41 indented by 3 more spaces. When set to a value of 0,
42 this process is reversed, causing the indent to decrease by
43 3 spaces. The default indentation level is 0.
46 When set to a value of 1, this turns on dbg() output for
47 for program importing this module, until told to do otherwise.
48 When set to a value of 0, dbg output is turned off. (dbg
49 output is off by default.)
52 When set to a value of 1, this increments the current
53 "suspension" level. This makes it possible for a function
54 to temporarily suspend its and any of its dependents'
55 potential outputs that use the same Logger instance.
56 When set to a value of 0, the suspension level is
57 decremented. When the value goes back to 0, potential
58 logging is resumed (actual output depends on the
59 "enable" status of the Logger instance in question.)
62 When set to a value of 1, the output will be sent to the
66 When set to a non-None value, the current output stream
67 (default of sys.stdout) is pushed onto a stack of streams,
68 and is replaced in the dbg system with the specified stream.
69 When called with a value of None, the previous stream will
70 be restored (if stacked.) If set to None without previously
71 changing it will result in no action being taken.
73 You can also call the log function implicitly on the Logger
74 instance, ie. you can type:
75 from wxPython.tools.dbg import Logger
77 dbg('something to print')
79 Using this fairly simple mechanism, it is possible to get fairly
80 useful debugging output in a program. Consider the following
83 >>> d = {1:'a', 2:'dictionary', 3:'of', 4:'words'}
84 >>> dbg = dbg.Logger('module')
88 ... dbg('foo', indent=1)
90 ... dbg('end of foo', indent=0)
93 ... dbg('bar', indent=1)
94 ... dbg('contents of d:', indent=1)
97 ... for key, value in l:
98 ... dbg('%d =' % key, value)
100 ... dbg('end of bar', indent=0)
105 module: contents of d:
107 module: 2 = dictionary
118 def __init__(self
, name
=None):
121 self
._indent
= 0 # current number of indentations
122 self
._dbg
= 0 # enable/disable flag
123 self
._suspend
= 0 # allows code to "suspend/resume" potential dbg output
124 self
._wxLog
= 0 # use wxLogMessage for debug output
125 self
._outstream
= sys
.stdout
# default output stream
126 self
._outstream
_stack
= [] # for restoration of streams as necessary
136 def log(self
, *args
, **kwargs
):
138 This function provides a useful framework for generating
139 optional debugging output that can be displayed at an
140 arbitrary level of indentation.
142 if not self
._dbg
and not 'enable' in kwargs
.keys():
145 if self
._dbg
and len(args
) and not self
._suspend
:
146 # (emulate print functionality)
147 strs
= [str(arg
) for arg
in args
]
148 output
= ' '.join(strs
)
149 if self
.name
: output
= self
.name
+': ' + output
150 output
= ' ' * 3 * self
._indent
+ output
153 from wxPython
.wx
import wxLogMessage
# (if not already imported)
156 self
._outstream
.write(output
+ '\n')
157 self
._outstream
.flush()
161 for kwarg
, value
in kwargs
.items():
162 if kwarg
== 'indent':
163 self
.SetIndent(value
)
164 elif kwarg
== 'enable':
165 self
.SetEnabled(value
)
166 elif kwarg
== 'suspend':
167 self
.SetSuspend(value
)
168 elif kwarg
== 'wxlog':
170 elif kwarg
== 'stream':
171 self
.SetStream(value
)
173 # aliases for the log function
174 dbg
= log
# backwards compatible
176 __call__
= log
# this one lets you 'call' the instance directly
179 def SetEnabled(self
, value
):
184 self
.dbg('dbg enabled')
187 self
.dbg('dbg disabled')
191 def SetSuspend(self
, value
):
194 elif self
._suspend
> 0:
198 def SetIndent(self
, value
):
201 elif self
._indent
> 0:
205 def SetWxLog(self
, value
):
209 def SetStream(self
, value
):
211 self
._outstream
_stack
.append( self
._outstream
)
212 self
._outstream
= value
213 elif value
is None and len(self
._outstream
_stack
) > 0:
214 self
._outstream
= self
._outstream
_stack
.pop(-1)
217 #------------------------------------------------------------
219 if __name__
== "__main__":
220 from wxPython
.wx
import *
221 wxLog_SetActiveTarget( wxLogStderr() )
222 logger
= Logger('module')
225 logger('test __call__ interface')
226 dbg('testing wxLog output to stderr:', wxlog
=1, indent
=1)
228 dbg('testing wxLogNull:')
229 devnull
= wxLogNull()
230 dbg('4,5,6...') # shouldn't print, according to doc...
232 dbg('(resuming to wxLogStdErr)', '7,8,9...', indent
=0)
233 dbg('disabling wxLog output, switching to stderr:')
234 dbg(wxlog
=0, stream
=sys
.stderr
)
235 dbg(logger
._outstream
, 'switching back to stdout:')
237 dbg(logger
._outstream
)
239 dbg('foo:', indent
=1)
241 foo('testing dbg inside function')
243 def __init__(self
, name
):
244 Logger
.__init
__(self
, name
)
245 def enable(self
, value
):
246 self
.dbg(enable
=value
)
248 self
.dbg('foo:', indent
=1)
249 self
.dbg(str, indent
=0)
250 f
= bar('class mixin')
251 f
.foo("shouldn't print")
253 f
.foo("should print")
254 dbg('test completed.', enable
=0)
255 dbg('(double-checking ;-)')