1 |
|
# Orca |
2 |
|
# |
3 |
|
# Copyright 2005-2006 Sun Microsystems Inc. |
4 |
|
# |
5 |
|
# This library is free software; you can redistribute it and/or |
6 |
|
# modify it under the terms of the GNU Library General Public |
7 |
|
# License as published by the Free Software Foundation; either |
8 |
|
# version 2 of the License, or (at your option) any later version. |
9 |
|
# |
10 |
|
# This library is distributed in the hope that it will be useful, |
11 |
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 |
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 |
|
# Library General Public License for more details. |
14 |
|
# |
15 |
|
# You should have received a copy of the GNU Library General Public |
16 |
|
# License along with this library; if not, write to the |
17 |
|
# Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
18 |
|
# Boston, MA 02111-1307, USA. |
19 |
|
|
20 |
|
"""Provides debug utilities for Orca. Debugging is managed by a debug |
21 |
|
level, which is held in the debugLevel field. All other methods take |
22 |
|
a debug level, which is compared to the current debug level to |
23 |
1 |
determine if the content should be output.""" |
24 |
|
|
25 |
1 |
__id__ = "$Id: debug.py 2096 2007-03-05 17:05:38Z richb $" |
26 |
1 |
__version__ = "$Revision: 2096 $" |
27 |
1 |
__date__ = "$Date: 2007-03-05 09:05:38 -0800 (Mon, 05 Mar 2007) $" |
28 |
1 |
__copyright__ = "Copyright (c) 2005-2006 Sun Microsystems Inc." |
29 |
1 |
__license__ = "LGPL" |
30 |
|
|
31 |
1 |
import logging |
32 |
1 |
logging.basicConfig() |
33 |
|
|
34 |
1 |
log = logging.getLogger() |
35 |
|
|
36 |
|
# Set the level to INFO if you want the logging of speech and braille |
37 |
|
# output. |
38 |
|
# |
39 |
|
#log.setLevel(logging.INFO) |
40 |
|
|
41 |
1 |
import traceback |
42 |
|
|
43 |
|
# Used to turn off all debugging. |
44 |
|
# |
45 |
1 |
LEVEL_OFF = 10000 |
46 |
|
|
47 |
|
# Used to describe events of considerable importance and which will prevent |
48 |
|
# normal program execution. |
49 |
|
# |
50 |
1 |
LEVEL_SEVERE = 1000 |
51 |
|
|
52 |
|
# Used to decribe events of interest to end users or system managers or which |
53 |
|
# indicate potential problems, but which Orca can deal with without crashing. |
54 |
|
# |
55 |
1 |
LEVEL_WARNING = 900 |
56 |
|
|
57 |
|
# Used to indicate reasonably significant messages that make sense to end users |
58 |
|
# and system managers. |
59 |
|
# |
60 |
|
# For the purposes of Orca, LEVEL_INFO means display the text being sent to |
61 |
|
# speech and braille. |
62 |
|
# |
63 |
1 |
LEVEL_INFO = 800 |
64 |
|
|
65 |
|
# Used to indicate static configuration information to assist in debugging |
66 |
|
# problems that may be associated with a particular configuration. |
67 |
|
# |
68 |
|
# For the purposes of Orca, LEVEL_CONFIGURATION means display the various |
69 |
|
# apsects of whether a particular feature (e.g., speech, braille, etc.) |
70 |
|
# is enabled or not as well as details about that feature. |
71 |
|
# |
72 |
1 |
LEVEL_CONFIGURATION = 700 |
73 |
|
|
74 |
|
# Used for lowest volume of detailed tracing information. |
75 |
|
# |
76 |
|
# For the purposes of Orca, this is braille and keyboard input, script |
77 |
|
# activation and deletion, locus of focus changes, and visual changes |
78 |
|
# to the locus of focus. |
79 |
|
# |
80 |
1 |
LEVEL_FINE = 600 |
81 |
|
|
82 |
|
# Used for medium volume of detailed tracing information. |
83 |
|
# |
84 |
|
# For the purposes of Orca, this is for debugging speech and braille |
85 |
|
# generators and tracking the synthesis of device events. |
86 |
|
# |
87 |
1 |
LEVEL_FINER = 500 |
88 |
|
|
89 |
|
# Used for maximum volume of detailed tracing information. |
90 |
|
# |
91 |
|
# For the purposes of Orca, this is for tracking all AT-SPI object |
92 |
|
# events. NOTE that one can up the debug level of AT-SPI object |
93 |
|
# events by setting the eventDebugLevel. In addition, one can filter |
94 |
|
# events by setting eventDebugFilter to a regular expression that |
95 |
|
# matches event type names. |
96 |
|
# |
97 |
1 |
LEVEL_FINEST = 400 |
98 |
|
|
99 |
|
# Used for all detailed tracing information, even finer than LEVEL_FINEST |
100 |
|
# |
101 |
1 |
LEVEL_ALL = 0 |
102 |
|
|
103 |
1 |
debugLevel = LEVEL_SEVERE |
104 |
|
|
105 |
|
# The debug file. If this is not set, then all debug output is done |
106 |
|
# via stdout. If this is set, then all debug output is sent to the |
107 |
|
# file. This can be useful for debugging because one can pass in a |
108 |
|
# non-buffered file to better track down hangs. |
109 |
|
# |
110 |
1 |
debugFile = None |
111 |
|
|
112 |
|
# The debug filter should be either None (which means to match all |
113 |
|
# events) or a compiled regular expression from the 're' module (see |
114 |
|
# http://www.amk.ca/python/howto/regex/). The regular expression will |
115 |
|
# be used as a matching function - if the event type creates a match |
116 |
|
# in the regular expression, then it will be considered for output. A |
117 |
|
# typical call to this method might look like: |
118 |
|
# |
119 |
|
# debug.eventDebugFilter = rc.compile('focus:|window:activate') |
120 |
|
# |
121 |
1 |
eventDebugLevel = LEVEL_FINEST |
122 |
1 |
eventDebugFilter = None |
123 |
|
|
124 |
1 |
def printException(level): |
125 |
|
"""Prints out information regarding the current exception. |
126 |
|
|
127 |
|
Arguments: |
128 |
|
- level: the accepted debug level |
129 |
|
""" |
130 |
|
|
131 |
334 |
if level >= debugLevel: |
132 |
207 |
println(level) |
133 |
207 |
traceback.print_exc(100, debugFile) |
134 |
207 |
println(level) |
135 |
|
|
136 |
1 |
def printStack(level): |
137 |
|
"""Prints out the current stack. |
138 |
|
|
139 |
|
Arguments: |
140 |
|
- level: the accepted debug level |
141 |
|
""" |
142 |
|
|
143 |
0 |
if level >= debugLevel: |
144 |
0 |
println(level) |
145 |
0 |
traceback.print_stack(None, 100, debugFile) |
146 |
0 |
println(level) |
147 |
|
|
148 |
1 |
def println(level, text = ""): |
149 |
|
"""Prints the text to stdout if debug is enabled. |
150 |
|
|
151 |
|
Arguments: |
152 |
|
- level: the accepted debug level |
153 |
|
- text: the text to print (default is a blank line) |
154 |
|
""" |
155 |
|
|
156 |
173152 |
if level >= debugLevel: |
157 |
7376 |
if debugFile: |
158 |
7376 |
debugFile.writelines([text,"\n"]) |
159 |
|
else: |
160 |
0 |
print text |
161 |
|
|
162 |
1 |
def printObjectEvent(level, event, sourceInfo=None): |
163 |
|
"""Prints out an Python Event object. The given level may be |
164 |
|
overridden if the eventDebugLevel is greater. Furthermore, only |
165 |
|
events with event types matching the eventDebugFilter regular |
166 |
|
expression will be printed. |
167 |
|
|
168 |
|
Arguments: |
169 |
|
- level: the accepted debug level |
170 |
|
- event: the Python Event to print |
171 |
|
- sourceInfo: additional string to print out |
172 |
|
""" |
173 |
|
|
174 |
22016 |
if eventDebugFilter and not eventDebugFilter.match(event.type): |
175 |
0 |
return |
176 |
|
|
177 |
22016 |
level = max(level, eventDebugLevel) |
178 |
|
|
179 |
22016 |
text = "OBJECT EVENT: %-40s detail=(%d,%d)" \ |
180 |
|
% (event.type, event.detail1, event.detail2) |
181 |
22016 |
println(level, text) |
182 |
|
|
183 |
22016 |
if sourceInfo: |
184 |
1152 |
println(level, " " + sourceInfo) |
185 |
|
|
186 |
1 |
def printInputEvent(level, string): |
187 |
|
"""Prints out an input event. The given level may be overridden |
188 |
|
if the eventDebugLevel (see setEventDebugLevel) is greater. |
189 |
|
|
190 |
|
Arguments: |
191 |
|
- level: the accepted debug level |
192 |
|
- string: the string representing the input event |
193 |
|
""" |
194 |
|
|
195 |
3257 |
println(max(level, eventDebugLevel), string) |
196 |
|
|
197 |
1 |
def printDetails(level, indent, accessible, includeApp=True): |
198 |
|
"""Lists the details of the given accessible with the given |
199 |
|
indentation. |
200 |
|
|
201 |
|
Arguments: |
202 |
|
- level: the accepted debug level |
203 |
|
- indent: a string containing spaces for indentation |
204 |
|
- accessible: the accessible whose details are to be listed |
205 |
|
- includeApp: if True, include information about the app |
206 |
|
""" |
207 |
|
|
208 |
20403 |
if level >= debugLevel and accessible: |
209 |
0 |
println(level, accessible.toString(indent, includeApp)) |
210 |
|
|
211 |
|
# The following code has been borrowed from the following URL: |
212 |
|
# |
213 |
|
# http://www.dalkescientific.com/writings/diary/archive/2005/04/20/tracing_python_code.html |
214 |
|
# |
215 |
1 |
import linecache |
216 |
|
|
217 |
1 |
def traceit(frame, event, arg): |
218 |
|
"""Line tracing utility to output all lines as they are executed by |
219 |
|
the interpreter. This is to be used by sys.settrace and is for |
220 |
|
debugging purposes. |
221 |
|
|
222 |
|
Arguments: |
223 |
|
- frame: is the current stack frame |
224 |
|
- event: 'call', 'line', 'return', 'exception', 'c_call', 'c_return', |
225 |
|
or 'c_exception' |
226 |
|
- arg: depends on the event type (see docs for sys.settrace) |
227 |
|
""" |
228 |
|
|
229 |
0 |
if event == "line": |
230 |
0 |
lineno = frame.f_lineno |
231 |
0 |
filename = frame.f_globals["__file__"] |
232 |
0 |
if (filename.endswith(".pyc") or |
233 |
|
filename.endswith(".pyo")): |
234 |
0 |
filename = filename[:-1] |
235 |
0 |
name = frame.f_globals["__name__"] |
236 |
0 |
if name == "gettext" \ |
237 |
|
or name == "locale" \ |
238 |
|
or name == "posixpath" \ |
239 |
|
or name == "UserDict": |
240 |
0 |
return traceit |
241 |
0 |
line = linecache.getline(filename, lineno) |
242 |
0 |
println(LEVEL_ALL, "TRACE %s:%s: %s" % (name, lineno, line.rstrip())) |
243 |
0 |
return traceit |