-
Notifications
You must be signed in to change notification settings - Fork 14
Expand file tree
/
Copy pathdebug.py
More file actions
152 lines (115 loc) · 4.71 KB
/
debug.py
File metadata and controls
152 lines (115 loc) · 4.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# debug.py
# The Raskin Center for Humane Interfaces (RCHI) 2004
# This work is licensed under the Creative Commons
# Attribution-NonCommercial-ShareAlike License. To view
# a copy of this license, visit
# http://creativecommons.org/licenses/by-nc-sa/2.0/
# or send a letter to :
# Creative Commons
# 559 Nathan Abbott Way
# Stanford, California 94305,
# USA.
# --- --- ---
# This module offers debugging-related functionality to Archy in the form of debug message logging, web-based bug reporting, and so forth.
# The following "developer mode" flag determines whether certain features are enabled or disabled for development purposes--for instance, turning developer mode on disables web-based bug reporting, since a developer using Archy is going to run into numerous bugs while writing code and can just fix the bugs as they find them.
DEVELOPER_MODE = True
# --------------------------
# The Debug Log Class
# --------------------------
# The debug log class (and its supporting classes) offer a file object that is meant to redirect stdio and stderr into a debug log file, while also displaying their messages to the "original" stdin and stdout.
class _DebugLogFileProxy:
def __init__(self, parent, number):
self.softspace = 0
self.parent = parent
self.number = number
def readline(self):
return None
def isatty(self):
return 0
def flush(self):
self.parent._flush(self.number)
def write(self, text):
self.parent._write(self.number, text)
def writelines(self, lines):
self.parent._writelines(self.number, lines)
class DebugLog:
def __init__(self, filename):
self.debug_out = _DebugLogFileProxy(self, 0)
self.debug_err = _DebugLogFileProxy(self, 1)
self.filename = filename
import threading
self.semaphore = threading.Semaphore()
def install(self):
import sys
self.file = open(self.filename, "a")
self.chain_files = [None, None]
self.chain_files[0] = sys.stdout
self.chain_files[1] = sys.stderr
sys.stdout = self.debug_out
sys.stderr = self.debug_err
def uninstall(self):
import sys
sys.stdout = self.chain_files[0]
sys.stderr = self.chain_files[1]
self.file.close()
def _flush(self, number):
self.semaphore.acquire()
self.chain_files[number].flush()
self.file.flush()
self.semaphore.release()
def _write(self, number, text):
self.semaphore.acquire()
self.chain_files[number].write(text)
self.file.write(text)
self.semaphore.release()
def _writelines(self, number, lines):
self.semaphore.acquire()
self.chain_files[number].writelines(lines)
self.file.writelines(lines)
self.semaphore.release()
# --------------------------
# Module functions
# --------------------------
def _get_windows_version():
import sys
WINDOWS_VERSIONS = {
0 : 'Win32s on Windows 3.1',
1 : 'Windows 95/98/ME',
2 : 'Windows NT',
3 : 'Windows CE'
}
info = sys.getwindowsversion()
info_str = "%s v%d.%d %s, build %d" % (
WINDOWS_VERSIONS[info[3]], info[0], info[1],
info[4], info[2])
return info_str
# This function returns a string containing lots of useful information about the system the application is running on.
def get_system_info():
import sys
import version
text = "System information:\n"
text += " Archy version: %s\n" % str(version.get_full_version())
text += " Command-line arguments: %s\n" % str(sys.argv)
if sys.platform == 'win32':
text += " Platform: %s\n" % _get_windows_version()
else:
text += " Platform: %s\n" % str(sys.platform)
text += " Python version: %s\n" % str(sys.version)
return text
# This function reports a bug using Archy's web-based bug reporting mechanism. If developer mode is on, however, it does nothing.
def report_bug(title, traceback_info):
import urllib, webbrowser
print traceback_info
if DEVELOPER_MODE:
return
traceback_info = get_system_info() + "\n" + traceback_info
query = {'title':title, 'traceback_info':traceback_info, 'type':'entry'}
url = 'http://www.raskincenter.org/cgi-bin/bug_entry.cgi?' + urllib.urlencode(query)
webbrowser.open(url)
# This function returns a printed version of the current traceback as a Python string.
def get_traceback():
import traceback
import cStringIO
newStrFile = cStringIO.StringIO()
traceback.print_exc(1000, newStrFile)
return newStrFile.getvalue()