]> git.proxmox.com Git - mirror_edk2.git/blame - AppPkg/Applications/Python/Python-2.7.2/Lib/cgitb.py
EmbeddedPkg: Extend NvVarStoreFormattedLib LIBRARY_CLASS
[mirror_edk2.git] / AppPkg / Applications / Python / Python-2.7.2 / Lib / cgitb.py
CommitLineData
4710c53d 1"""More comprehensive traceback formatting for Python scripts.\r
2\r
3To enable this module, do:\r
4\r
5 import cgitb; cgitb.enable()\r
6\r
7at the top of your script. The optional arguments to enable() are:\r
8\r
9 display - if true, tracebacks are displayed in the web browser\r
10 logdir - if set, tracebacks are written to files in this directory\r
11 context - number of lines of source code to show for each stack frame\r
12 format - 'text' or 'html' controls the output format\r
13\r
14By default, tracebacks are displayed but not saved, the context is 5 lines\r
15and the output format is 'html' (for backwards compatibility with the\r
16original use of this module)\r
17\r
18Alternatively, if you have caught an exception and want cgitb to display it\r
19for you, call cgitb.handler(). The optional argument to handler() is a\r
203-item tuple (etype, evalue, etb) just like the value of sys.exc_info().\r
21The default handler displays output as HTML.\r
22\r
23"""\r
24import inspect\r
25import keyword\r
26import linecache\r
27import os\r
28import pydoc\r
29import sys\r
30import tempfile\r
31import time\r
32import tokenize\r
33import traceback\r
34import types\r
35\r
36def reset():\r
37 """Return a string that resets the CGI and browser to a known state."""\r
38 return '''<!--: spam\r
39Content-Type: text/html\r
40\r
41<body bgcolor="#f0f0f8"><font color="#f0f0f8" size="-5"> -->\r
42<body bgcolor="#f0f0f8"><font color="#f0f0f8" size="-5"> --> -->\r
43</font> </font> </font> </script> </object> </blockquote> </pre>\r
44</table> </table> </table> </table> </table> </font> </font> </font>'''\r
45\r
46__UNDEF__ = [] # a special sentinel object\r
47def small(text):\r
48 if text:\r
49 return '<small>' + text + '</small>'\r
50 else:\r
51 return ''\r
52\r
53def strong(text):\r
54 if text:\r
55 return '<strong>' + text + '</strong>'\r
56 else:\r
57 return ''\r
58\r
59def grey(text):\r
60 if text:\r
61 return '<font color="#909090">' + text + '</font>'\r
62 else:\r
63 return ''\r
64\r
65def lookup(name, frame, locals):\r
66 """Find the value for a given name in the given environment."""\r
67 if name in locals:\r
68 return 'local', locals[name]\r
69 if name in frame.f_globals:\r
70 return 'global', frame.f_globals[name]\r
71 if '__builtins__' in frame.f_globals:\r
72 builtins = frame.f_globals['__builtins__']\r
73 if type(builtins) is type({}):\r
74 if name in builtins:\r
75 return 'builtin', builtins[name]\r
76 else:\r
77 if hasattr(builtins, name):\r
78 return 'builtin', getattr(builtins, name)\r
79 return None, __UNDEF__\r
80\r
81def scanvars(reader, frame, locals):\r
82 """Scan one logical line of Python and look up values of variables used."""\r
83 vars, lasttoken, parent, prefix, value = [], None, None, '', __UNDEF__\r
84 for ttype, token, start, end, line in tokenize.generate_tokens(reader):\r
85 if ttype == tokenize.NEWLINE: break\r
86 if ttype == tokenize.NAME and token not in keyword.kwlist:\r
87 if lasttoken == '.':\r
88 if parent is not __UNDEF__:\r
89 value = getattr(parent, token, __UNDEF__)\r
90 vars.append((prefix + token, prefix, value))\r
91 else:\r
92 where, value = lookup(token, frame, locals)\r
93 vars.append((token, where, value))\r
94 elif token == '.':\r
95 prefix += lasttoken + '.'\r
96 parent = value\r
97 else:\r
98 parent, prefix = None, ''\r
99 lasttoken = token\r
100 return vars\r
101\r
102def html(einfo, context=5):\r
103 """Return a nice HTML document describing a given traceback."""\r
104 etype, evalue, etb = einfo\r
105 if type(etype) is types.ClassType:\r
106 etype = etype.__name__\r
107 pyver = 'Python ' + sys.version.split()[0] + ': ' + sys.executable\r
108 date = time.ctime(time.time())\r
109 head = '<body bgcolor="#f0f0f8">' + pydoc.html.heading(\r
110 '<big><big>%s</big></big>' %\r
111 strong(pydoc.html.escape(str(etype))),\r
112 '#ffffff', '#6622aa', pyver + '<br>' + date) + '''\r
113<p>A problem occurred in a Python script. Here is the sequence of\r
114function calls leading up to the error, in the order they occurred.</p>'''\r
115\r
116 indent = '<tt>' + small('&nbsp;' * 5) + '&nbsp;</tt>'\r
117 frames = []\r
118 records = inspect.getinnerframes(etb, context)\r
119 for frame, file, lnum, func, lines, index in records:\r
120 if file:\r
121 file = os.path.abspath(file)\r
122 link = '<a href="file://%s">%s</a>' % (file, pydoc.html.escape(file))\r
123 else:\r
124 file = link = '?'\r
125 args, varargs, varkw, locals = inspect.getargvalues(frame)\r
126 call = ''\r
127 if func != '?':\r
128 call = 'in ' + strong(func) + \\r
129 inspect.formatargvalues(args, varargs, varkw, locals,\r
130 formatvalue=lambda value: '=' + pydoc.html.repr(value))\r
131\r
132 highlight = {}\r
133 def reader(lnum=[lnum]):\r
134 highlight[lnum[0]] = 1\r
135 try: return linecache.getline(file, lnum[0])\r
136 finally: lnum[0] += 1\r
137 vars = scanvars(reader, frame, locals)\r
138\r
139 rows = ['<tr><td bgcolor="#d8bbff">%s%s %s</td></tr>' %\r
140 ('<big>&nbsp;</big>', link, call)]\r
141 if index is not None:\r
142 i = lnum - index\r
143 for line in lines:\r
144 num = small('&nbsp;' * (5-len(str(i))) + str(i)) + '&nbsp;'\r
145 if i in highlight:\r
146 line = '<tt>=&gt;%s%s</tt>' % (num, pydoc.html.preformat(line))\r
147 rows.append('<tr><td bgcolor="#ffccee">%s</td></tr>' % line)\r
148 else:\r
149 line = '<tt>&nbsp;&nbsp;%s%s</tt>' % (num, pydoc.html.preformat(line))\r
150 rows.append('<tr><td>%s</td></tr>' % grey(line))\r
151 i += 1\r
152\r
153 done, dump = {}, []\r
154 for name, where, value in vars:\r
155 if name in done: continue\r
156 done[name] = 1\r
157 if value is not __UNDEF__:\r
158 if where in ('global', 'builtin'):\r
159 name = ('<em>%s</em> ' % where) + strong(name)\r
160 elif where == 'local':\r
161 name = strong(name)\r
162 else:\r
163 name = where + strong(name.split('.')[-1])\r
164 dump.append('%s&nbsp;= %s' % (name, pydoc.html.repr(value)))\r
165 else:\r
166 dump.append(name + ' <em>undefined</em>')\r
167\r
168 rows.append('<tr><td>%s</td></tr>' % small(grey(', '.join(dump))))\r
169 frames.append('''\r
170<table width="100%%" cellspacing=0 cellpadding=0 border=0>\r
171%s</table>''' % '\n'.join(rows))\r
172\r
173 exception = ['<p>%s: %s' % (strong(pydoc.html.escape(str(etype))),\r
174 pydoc.html.escape(str(evalue)))]\r
175 if isinstance(evalue, BaseException):\r
176 for name in dir(evalue):\r
177 if name[:1] == '_': continue\r
178 value = pydoc.html.repr(getattr(evalue, name))\r
179 exception.append('\n<br>%s%s&nbsp;=\n%s' % (indent, name, value))\r
180\r
181 return head + ''.join(frames) + ''.join(exception) + '''\r
182\r
183\r
184<!-- The above is a description of an error in a Python program, formatted\r
185 for a Web browser because the 'cgitb' module was enabled. In case you\r
186 are not reading this in a Web browser, here is the original traceback:\r
187\r
188%s\r
189-->\r
190''' % pydoc.html.escape(\r
191 ''.join(traceback.format_exception(etype, evalue, etb)))\r
192\r
193def text(einfo, context=5):\r
194 """Return a plain text document describing a given traceback."""\r
195 etype, evalue, etb = einfo\r
196 if type(etype) is types.ClassType:\r
197 etype = etype.__name__\r
198 pyver = 'Python ' + sys.version.split()[0] + ': ' + sys.executable\r
199 date = time.ctime(time.time())\r
200 head = "%s\n%s\n%s\n" % (str(etype), pyver, date) + '''\r
201A problem occurred in a Python script. Here is the sequence of\r
202function calls leading up to the error, in the order they occurred.\r
203'''\r
204\r
205 frames = []\r
206 records = inspect.getinnerframes(etb, context)\r
207 for frame, file, lnum, func, lines, index in records:\r
208 file = file and os.path.abspath(file) or '?'\r
209 args, varargs, varkw, locals = inspect.getargvalues(frame)\r
210 call = ''\r
211 if func != '?':\r
212 call = 'in ' + func + \\r
213 inspect.formatargvalues(args, varargs, varkw, locals,\r
214 formatvalue=lambda value: '=' + pydoc.text.repr(value))\r
215\r
216 highlight = {}\r
217 def reader(lnum=[lnum]):\r
218 highlight[lnum[0]] = 1\r
219 try: return linecache.getline(file, lnum[0])\r
220 finally: lnum[0] += 1\r
221 vars = scanvars(reader, frame, locals)\r
222\r
223 rows = [' %s %s' % (file, call)]\r
224 if index is not None:\r
225 i = lnum - index\r
226 for line in lines:\r
227 num = '%5d ' % i\r
228 rows.append(num+line.rstrip())\r
229 i += 1\r
230\r
231 done, dump = {}, []\r
232 for name, where, value in vars:\r
233 if name in done: continue\r
234 done[name] = 1\r
235 if value is not __UNDEF__:\r
236 if where == 'global': name = 'global ' + name\r
237 elif where != 'local': name = where + name.split('.')[-1]\r
238 dump.append('%s = %s' % (name, pydoc.text.repr(value)))\r
239 else:\r
240 dump.append(name + ' undefined')\r
241\r
242 rows.append('\n'.join(dump))\r
243 frames.append('\n%s\n' % '\n'.join(rows))\r
244\r
245 exception = ['%s: %s' % (str(etype), str(evalue))]\r
246 if isinstance(evalue, BaseException):\r
247 for name in dir(evalue):\r
248 value = pydoc.text.repr(getattr(evalue, name))\r
249 exception.append('\n%s%s = %s' % (" "*4, name, value))\r
250\r
251 return head + ''.join(frames) + ''.join(exception) + '''\r
252\r
253The above is a description of an error in a Python program. Here is\r
254the original traceback:\r
255\r
256%s\r
257''' % ''.join(traceback.format_exception(etype, evalue, etb))\r
258\r
259class Hook:\r
260 """A hook to replace sys.excepthook that shows tracebacks in HTML."""\r
261\r
262 def __init__(self, display=1, logdir=None, context=5, file=None,\r
263 format="html"):\r
264 self.display = display # send tracebacks to browser if true\r
265 self.logdir = logdir # log tracebacks to files if not None\r
266 self.context = context # number of source code lines per frame\r
267 self.file = file or sys.stdout # place to send the output\r
268 self.format = format\r
269\r
270 def __call__(self, etype, evalue, etb):\r
271 self.handle((etype, evalue, etb))\r
272\r
273 def handle(self, info=None):\r
274 info = info or sys.exc_info()\r
275 if self.format == "html":\r
276 self.file.write(reset())\r
277\r
278 formatter = (self.format=="html") and html or text\r
279 plain = False\r
280 try:\r
281 doc = formatter(info, self.context)\r
282 except: # just in case something goes wrong\r
283 doc = ''.join(traceback.format_exception(*info))\r
284 plain = True\r
285\r
286 if self.display:\r
287 if plain:\r
288 doc = doc.replace('&', '&amp;').replace('<', '&lt;')\r
289 self.file.write('<pre>' + doc + '</pre>\n')\r
290 else:\r
291 self.file.write(doc + '\n')\r
292 else:\r
293 self.file.write('<p>A problem occurred in a Python script.\n')\r
294\r
295 if self.logdir is not None:\r
296 suffix = ['.txt', '.html'][self.format=="html"]\r
297 (fd, path) = tempfile.mkstemp(suffix=suffix, dir=self.logdir)\r
298 try:\r
299 file = os.fdopen(fd, 'w')\r
300 file.write(doc)\r
301 file.close()\r
302 msg = '<p> %s contains the description of this error.' % path\r
303 except:\r
304 msg = '<p> Tried to save traceback to %s, but failed.' % path\r
305 self.file.write(msg + '\n')\r
306 try:\r
307 self.file.flush()\r
308 except: pass\r
309\r
310handler = Hook().handle\r
311def enable(display=1, logdir=None, context=5, format="html"):\r
312 """Install an exception handler that formats tracebacks as HTML.\r
313\r
314 The optional argument 'display' can be set to 0 to suppress sending the\r
315 traceback to the browser, and 'logdir' can be set to a directory to cause\r
316 tracebacks to be written to files there."""\r
317 sys.excepthook = Hook(display=display, logdir=logdir,\r
318 context=context, format=format)\r