Mercurial > cpython-lru_cache-weakref
annotate Lib/cgitb.py @ 87690:66c1c9f32567 default tip
Add use_weakref option to functools.lru_cache
The use_weakref option makes lru_cache create weak references to the function
arguments when creating the cache key, which prevents them from staying in the
memory forever even after all other references to them are gone.
This is a proof of concept for http://bugs.python.org/issue19859
| author | Radomir Dopieralski <devel@sheep.art.pl> |
|---|---|
| date | Tue, 03 Dec 2013 16:02:48 +0100 |
| parents | 45764e4bb504 |
| children |
| rev | line source |
|---|---|
|
29511
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
1 """More comprehensive traceback formatting for Python scripts. |
| 19365 | 2 |
| 3 To enable this module, do: | |
| 4 | |
| 5 import cgitb; cgitb.enable() | |
| 6 | |
|
29511
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
7 at the top of your script. The optional arguments to enable() are: |
| 19365 | 8 |
| 9 display - if true, tracebacks are displayed in the web browser | |
| 10 logdir - if set, tracebacks are written to files in this directory | |
| 19421 | 11 context - number of lines of source code to show for each stack frame |
|
29668
36a17904a3ed
Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents:
29511
diff
changeset
|
12 format - 'text' or 'html' controls the output format |
| 19365 | 13 |
|
29511
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
14 By default, tracebacks are displayed but not saved, the context is 5 lines |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
15 and the output format is 'html' (for backwards compatibility with the |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
16 original use of this module) |
| 19365 | 17 |
| 18 Alternatively, if you have caught an exception and want cgitb to display it | |
|
29511
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
19 for you, call cgitb.handler(). The optional argument to handler() is a |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
20 3-item tuple (etype, evalue, etb) just like the value of sys.exc_info(). |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
21 The default handler displays output as HTML. |
|
52650
46f1ce76199e
Merged revisions 70956 via svnmerge from
Brett Cannon <bcannon@gmail.com>
parents:
41986
diff
changeset
|
22 |
|
29511
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
23 """ |
|
52650
46f1ce76199e
Merged revisions 70956 via svnmerge from
Brett Cannon <bcannon@gmail.com>
parents:
41986
diff
changeset
|
24 import inspect |
|
46f1ce76199e
Merged revisions 70956 via svnmerge from
Brett Cannon <bcannon@gmail.com>
parents:
41986
diff
changeset
|
25 import keyword |
|
46f1ce76199e
Merged revisions 70956 via svnmerge from
Brett Cannon <bcannon@gmail.com>
parents:
41986
diff
changeset
|
26 import linecache |
|
46f1ce76199e
Merged revisions 70956 via svnmerge from
Brett Cannon <bcannon@gmail.com>
parents:
41986
diff
changeset
|
27 import os |
|
46f1ce76199e
Merged revisions 70956 via svnmerge from
Brett Cannon <bcannon@gmail.com>
parents:
41986
diff
changeset
|
28 import pydoc |
|
21194
1519d6faab15
Add "file" argument to Hook constructor.
Ka-Ping Yee <ping@zesty.ca>
parents:
19421
diff
changeset
|
29 import sys |
|
52650
46f1ce76199e
Merged revisions 70956 via svnmerge from
Brett Cannon <bcannon@gmail.com>
parents:
41986
diff
changeset
|
30 import tempfile |
|
46f1ce76199e
Merged revisions 70956 via svnmerge from
Brett Cannon <bcannon@gmail.com>
parents:
41986
diff
changeset
|
31 import time |
|
46f1ce76199e
Merged revisions 70956 via svnmerge from
Brett Cannon <bcannon@gmail.com>
parents:
41986
diff
changeset
|
32 import tokenize |
|
46f1ce76199e
Merged revisions 70956 via svnmerge from
Brett Cannon <bcannon@gmail.com>
parents:
41986
diff
changeset
|
33 import traceback |
|
21194
1519d6faab15
Add "file" argument to Hook constructor.
Ka-Ping Yee <ping@zesty.ca>
parents:
19421
diff
changeset
|
34 |
| 19365 | 35 def reset(): |
| 36 """Return a string that resets the CGI and browser to a known state.""" | |
| 37 return '''<!--: spam | |
| 38 Content-Type: text/html | |
| 39 | |
| 19421 | 40 <body bgcolor="#f0f0f8"><font color="#f0f0f8" size="-5"> --> |
| 41 <body bgcolor="#f0f0f8"><font color="#f0f0f8" size="-5"> --> --> | |
| 19365 | 42 </font> </font> </font> </script> </object> </blockquote> </pre> |
| 43 </table> </table> </table> </table> </table> </font> </font> </font>''' | |
| 44 | |
| 19421 | 45 __UNDEF__ = [] # a special sentinel object |
|
32577
fef7911a5705
[Patch #987052 from Thomas Guettler]
Andrew M. Kuchling <amk@amk.ca>
parents:
32292
diff
changeset
|
46 def small(text): |
|
fef7911a5705
[Patch #987052 from Thomas Guettler]
Andrew M. Kuchling <amk@amk.ca>
parents:
32292
diff
changeset
|
47 if text: |
|
fef7911a5705
[Patch #987052 from Thomas Guettler]
Andrew M. Kuchling <amk@amk.ca>
parents:
32292
diff
changeset
|
48 return '<small>' + text + '</small>' |
|
fef7911a5705
[Patch #987052 from Thomas Guettler]
Andrew M. Kuchling <amk@amk.ca>
parents:
32292
diff
changeset
|
49 else: |
|
fef7911a5705
[Patch #987052 from Thomas Guettler]
Andrew M. Kuchling <amk@amk.ca>
parents:
32292
diff
changeset
|
50 return '' |
|
32736
c3a096bfbd6b
Whitespace normalization, via reindent.py.
Tim Peters <tim.peters@gmail.com>
parents:
32577
diff
changeset
|
51 |
|
32577
fef7911a5705
[Patch #987052 from Thomas Guettler]
Andrew M. Kuchling <amk@amk.ca>
parents:
32292
diff
changeset
|
52 def strong(text): |
|
fef7911a5705
[Patch #987052 from Thomas Guettler]
Andrew M. Kuchling <amk@amk.ca>
parents:
32292
diff
changeset
|
53 if text: |
|
fef7911a5705
[Patch #987052 from Thomas Guettler]
Andrew M. Kuchling <amk@amk.ca>
parents:
32292
diff
changeset
|
54 return '<strong>' + text + '</strong>' |
|
fef7911a5705
[Patch #987052 from Thomas Guettler]
Andrew M. Kuchling <amk@amk.ca>
parents:
32292
diff
changeset
|
55 else: |
|
fef7911a5705
[Patch #987052 from Thomas Guettler]
Andrew M. Kuchling <amk@amk.ca>
parents:
32292
diff
changeset
|
56 return '' |
|
32736
c3a096bfbd6b
Whitespace normalization, via reindent.py.
Tim Peters <tim.peters@gmail.com>
parents:
32577
diff
changeset
|
57 |
|
32577
fef7911a5705
[Patch #987052 from Thomas Guettler]
Andrew M. Kuchling <amk@amk.ca>
parents:
32292
diff
changeset
|
58 def grey(text): |
|
fef7911a5705
[Patch #987052 from Thomas Guettler]
Andrew M. Kuchling <amk@amk.ca>
parents:
32292
diff
changeset
|
59 if text: |
|
fef7911a5705
[Patch #987052 from Thomas Guettler]
Andrew M. Kuchling <amk@amk.ca>
parents:
32292
diff
changeset
|
60 return '<font color="#909090">' + text + '</font>' |
|
fef7911a5705
[Patch #987052 from Thomas Guettler]
Andrew M. Kuchling <amk@amk.ca>
parents:
32292
diff
changeset
|
61 else: |
|
fef7911a5705
[Patch #987052 from Thomas Guettler]
Andrew M. Kuchling <amk@amk.ca>
parents:
32292
diff
changeset
|
62 return '' |
| 19421 | 63 |
| 64 def lookup(name, frame, locals): | |
| 65 """Find the value for a given name in the given environment.""" | |
| 66 if name in locals: | |
| 67 return 'local', locals[name] | |
| 68 if name in frame.f_globals: | |
| 69 return 'global', frame.f_globals[name] | |
|
23998
dab8701bd3fa
Also look up variable names in __builtins__ if not found in globals.
Ka-Ping Yee <ping@zesty.ca>
parents:
21480
diff
changeset
|
70 if '__builtins__' in frame.f_globals: |
|
dab8701bd3fa
Also look up variable names in __builtins__ if not found in globals.
Ka-Ping Yee <ping@zesty.ca>
parents:
21480
diff
changeset
|
71 builtins = frame.f_globals['__builtins__'] |
|
dab8701bd3fa
Also look up variable names in __builtins__ if not found in globals.
Ka-Ping Yee <ping@zesty.ca>
parents:
21480
diff
changeset
|
72 if type(builtins) is type({}): |
|
dab8701bd3fa
Also look up variable names in __builtins__ if not found in globals.
Ka-Ping Yee <ping@zesty.ca>
parents:
21480
diff
changeset
|
73 if name in builtins: |
|
dab8701bd3fa
Also look up variable names in __builtins__ if not found in globals.
Ka-Ping Yee <ping@zesty.ca>
parents:
21480
diff
changeset
|
74 return 'builtin', builtins[name] |
|
dab8701bd3fa
Also look up variable names in __builtins__ if not found in globals.
Ka-Ping Yee <ping@zesty.ca>
parents:
21480
diff
changeset
|
75 else: |
|
dab8701bd3fa
Also look up variable names in __builtins__ if not found in globals.
Ka-Ping Yee <ping@zesty.ca>
parents:
21480
diff
changeset
|
76 if hasattr(builtins, name): |
|
dab8701bd3fa
Also look up variable names in __builtins__ if not found in globals.
Ka-Ping Yee <ping@zesty.ca>
parents:
21480
diff
changeset
|
77 return 'builtin', getattr(builtins, name) |
| 19421 | 78 return None, __UNDEF__ |
| 79 | |
| 80 def scanvars(reader, frame, locals): | |
| 81 """Scan one logical line of Python and look up values of variables used.""" | |
|
32263
b9c9e7e8be7d
[Bug #758665] cgitb.scanvars() fails because of an unititialized value variable. Patch from Robin Becker.
Andrew M. Kuchling <amk@amk.ca>
parents:
32001
diff
changeset
|
82 vars, lasttoken, parent, prefix, value = [], None, None, '', __UNDEF__ |
| 19421 | 83 for ttype, token, start, end, line in tokenize.generate_tokens(reader): |
| 84 if ttype == tokenize.NEWLINE: break | |
| 85 if ttype == tokenize.NAME and token not in keyword.kwlist: | |
| 86 if lasttoken == '.': | |
| 87 if parent is not __UNDEF__: | |
| 88 value = getattr(parent, token, __UNDEF__) | |
| 89 vars.append((prefix + token, prefix, value)) | |
| 90 else: | |
| 91 where, value = lookup(token, frame, locals) | |
| 92 vars.append((token, where, value)) | |
| 93 elif token == '.': | |
| 94 prefix += lasttoken + '.' | |
| 95 parent = value | |
| 96 else: | |
| 97 parent, prefix = None, '' | |
| 98 lasttoken = token | |
| 99 return vars | |
| 100 | |
|
41717
9ad84070b22d
Merged revisions 55328-55341 via svnmerge from
Guido van Rossum <guido@python.org>
parents:
41437
diff
changeset
|
101 def html(einfo, context=5): |
| 19421 | 102 """Return a nice HTML document describing a given traceback.""" |
|
41717
9ad84070b22d
Merged revisions 55328-55341 via svnmerge from
Guido van Rossum <guido@python.org>
parents:
41437
diff
changeset
|
103 etype, evalue, etb = einfo |
|
41986
6464cc638faa
Merged revisions 55795-55816 via svnmerge from
Guido van Rossum <guido@python.org>
parents:
41824
diff
changeset
|
104 if isinstance(etype, type): |
| 19365 | 105 etype = etype.__name__ |
| 106 pyver = 'Python ' + sys.version.split()[0] + ': ' + sys.executable | |
| 107 date = time.ctime(time.time()) | |
| 19421 | 108 head = '<body bgcolor="#f0f0f8">' + pydoc.html.heading( |
|
32577
fef7911a5705
[Patch #987052 from Thomas Guettler]
Andrew M. Kuchling <amk@amk.ca>
parents:
32292
diff
changeset
|
109 '<big><big>%s</big></big>' % |
|
fef7911a5705
[Patch #987052 from Thomas Guettler]
Andrew M. Kuchling <amk@amk.ca>
parents:
32292
diff
changeset
|
110 strong(pydoc.html.escape(str(etype))), |
| 19421 | 111 '#ffffff', '#6622aa', pyver + '<br>' + date) + ''' |
| 112 <p>A problem occurred in a Python script. Here is the sequence of | |
|
32577
fef7911a5705
[Patch #987052 from Thomas Guettler]
Andrew M. Kuchling <amk@amk.ca>
parents:
32292
diff
changeset
|
113 function calls leading up to the error, in the order they occurred.</p>''' |
| 19365 | 114 |
| 19421 | 115 indent = '<tt>' + small(' ' * 5) + ' </tt>' |
| 19365 | 116 frames = [] |
| 117 records = inspect.getinnerframes(etb, context) | |
| 118 for frame, file, lnum, func, lines, index in records: | |
|
35154
a31a770bb778
Prevent creating a HTML link to file://?/
Georg Brandl <georg@python.org>
parents:
34545
diff
changeset
|
119 if file: |
|
a31a770bb778
Prevent creating a HTML link to file://?/
Georg Brandl <georg@python.org>
parents:
34545
diff
changeset
|
120 file = os.path.abspath(file) |
|
a31a770bb778
Prevent creating a HTML link to file://?/
Georg Brandl <georg@python.org>
parents:
34545
diff
changeset
|
121 link = '<a href="file://%s">%s</a>' % (file, pydoc.html.escape(file)) |
|
a31a770bb778
Prevent creating a HTML link to file://?/
Georg Brandl <georg@python.org>
parents:
34545
diff
changeset
|
122 else: |
|
a31a770bb778
Prevent creating a HTML link to file://?/
Georg Brandl <georg@python.org>
parents:
34545
diff
changeset
|
123 file = link = '?' |
| 19365 | 124 args, varargs, varkw, locals = inspect.getargvalues(frame) |
| 19421 | 125 call = '' |
| 126 if func != '?': | |
| 127 call = 'in ' + strong(func) + \ | |
| 128 inspect.formatargvalues(args, varargs, varkw, locals, | |
| 129 formatvalue=lambda value: '=' + pydoc.html.repr(value)) | |
| 19365 | 130 |
| 19421 | 131 highlight = {} |
| 132 def reader(lnum=[lnum]): | |
| 133 highlight[lnum[0]] = 1 | |
| 134 try: return linecache.getline(file, lnum[0]) | |
| 135 finally: lnum[0] += 1 | |
| 136 vars = scanvars(reader, frame, locals) | |
| 19365 | 137 |
| 19421 | 138 rows = ['<tr><td bgcolor="#d8bbff">%s%s %s</td></tr>' % |
| 139 ('<big> </big>', link, call)] | |
| 19365 | 140 if index is not None: |
| 141 i = lnum - index | |
| 142 for line in lines: | |
| 19421 | 143 num = small(' ' * (5-len(str(i))) + str(i)) + ' ' |
| 144 if i in highlight: | |
|
53072
7e978ca42930
Merged revisions 70980,71059,71225,71234,71241,71243,71249,71251,71255,71266,71299,71329,71397-71398,71486 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents:
52650
diff
changeset
|
145 line = '<tt>=>%s%s</tt>' % (num, pydoc.html.preformat(line)) |
| 19421 | 146 rows.append('<tr><td bgcolor="#ffccee">%s</td></tr>' % line) |
| 147 else: | |
|
53072
7e978ca42930
Merged revisions 70980,71059,71225,71234,71241,71243,71249,71251,71255,71266,71299,71329,71397-71398,71486 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents:
52650
diff
changeset
|
148 line = '<tt> %s%s</tt>' % (num, pydoc.html.preformat(line)) |
| 19421 | 149 rows.append('<tr><td>%s</td></tr>' % grey(line)) |
| 150 i += 1 | |
| 19365 | 151 |
| 19421 | 152 done, dump = {}, [] |
| 153 for name, where, value in vars: | |
| 154 if name in done: continue | |
| 155 done[name] = 1 | |
| 156 if value is not __UNDEF__: | |
|
34545
9d66fba78444
Replace list of constants with tuples of constants.
Raymond Hettinger <python@rcn.com>
parents:
32736
diff
changeset
|
157 if where in ('global', 'builtin'): |
|
23998
dab8701bd3fa
Also look up variable names in __builtins__ if not found in globals.
Ka-Ping Yee <ping@zesty.ca>
parents:
21480
diff
changeset
|
158 name = ('<em>%s</em> ' % where) + strong(name) |
|
dab8701bd3fa
Also look up variable names in __builtins__ if not found in globals.
Ka-Ping Yee <ping@zesty.ca>
parents:
21480
diff
changeset
|
159 elif where == 'local': |
|
dab8701bd3fa
Also look up variable names in __builtins__ if not found in globals.
Ka-Ping Yee <ping@zesty.ca>
parents:
21480
diff
changeset
|
160 name = strong(name) |
|
dab8701bd3fa
Also look up variable names in __builtins__ if not found in globals.
Ka-Ping Yee <ping@zesty.ca>
parents:
21480
diff
changeset
|
161 else: |
|
dab8701bd3fa
Also look up variable names in __builtins__ if not found in globals.
Ka-Ping Yee <ping@zesty.ca>
parents:
21480
diff
changeset
|
162 name = where + strong(name.split('.')[-1]) |
| 19421 | 163 dump.append('%s = %s' % (name, pydoc.html.repr(value))) |
| 164 else: | |
| 165 dump.append(name + ' <em>undefined</em>') | |
| 166 | |
| 167 rows.append('<tr><td>%s</td></tr>' % small(grey(', '.join(dump)))) | |
|
32577
fef7911a5705
[Patch #987052 from Thomas Guettler]
Andrew M. Kuchling <amk@amk.ca>
parents:
32292
diff
changeset
|
168 frames.append(''' |
| 19421 | 169 <table width="100%%" cellspacing=0 cellpadding=0 border=0> |
| 170 %s</table>''' % '\n'.join(rows)) | |
| 171 | |
|
31850
696f4ba9ddf7
[Bugfix candidate] Escape traceback type and value. There are probably additional cases where cgitb.py doesn't escape as paranoidly as it should (e.g. attribute names)
Andrew M. Kuchling <amk@amk.ca>
parents:
29668
diff
changeset
|
172 exception = ['<p>%s: %s' % (strong(pydoc.html.escape(str(etype))), |
|
696f4ba9ddf7
[Bugfix candidate] Escape traceback type and value. There are probably additional cases where cgitb.py doesn't escape as paranoidly as it should (e.g. attribute names)
Andrew M. Kuchling <amk@amk.ca>
parents:
29668
diff
changeset
|
173 pydoc.html.escape(str(evalue)))] |
|
41437
3667d1a8c916
Bug #1697782: remove all remaining code that uses types.InstanceType.
Georg Brandl <georg@python.org>
parents:
35742
diff
changeset
|
174 for name in dir(evalue): |
|
3667d1a8c916
Bug #1697782: remove all remaining code that uses types.InstanceType.
Georg Brandl <georg@python.org>
parents:
35742
diff
changeset
|
175 if name[:1] == '_': continue |
|
3667d1a8c916
Bug #1697782: remove all remaining code that uses types.InstanceType.
Georg Brandl <georg@python.org>
parents:
35742
diff
changeset
|
176 value = pydoc.html.repr(getattr(evalue, name)) |
|
3667d1a8c916
Bug #1697782: remove all remaining code that uses types.InstanceType.
Georg Brandl <georg@python.org>
parents:
35742
diff
changeset
|
177 exception.append('\n<br>%s%s =\n%s' % (indent, name, value)) |
| 19365 | 178 |
| 179 return head + ''.join(frames) + ''.join(exception) + ''' | |
| 180 | |
| 181 | |
| 19421 | 182 <!-- The above is a description of an error in a Python program, formatted |
| 183 for a Web browser because the 'cgitb' module was enabled. In case you | |
| 184 are not reading this in a Web browser, here is the original traceback: | |
| 19365 | 185 |
| 186 %s | |
| 187 --> | |
|
41824
24b60622b944
Merged revisions 55407-55513 via svnmerge from
Guido van Rossum <guido@python.org>
parents:
41717
diff
changeset
|
188 ''' % pydoc.html.escape( |
|
24b60622b944
Merged revisions 55407-55513 via svnmerge from
Guido van Rossum <guido@python.org>
parents:
41717
diff
changeset
|
189 ''.join(traceback.format_exception(etype, evalue, etb))) |
| 19365 | 190 |
|
41717
9ad84070b22d
Merged revisions 55328-55341 via svnmerge from
Guido van Rossum <guido@python.org>
parents:
41437
diff
changeset
|
191 def text(einfo, context=5): |
|
29511
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
192 """Return a plain text document describing a given traceback.""" |
|
41717
9ad84070b22d
Merged revisions 55328-55341 via svnmerge from
Guido van Rossum <guido@python.org>
parents:
41437
diff
changeset
|
193 etype, evalue, etb = einfo |
|
41986
6464cc638faa
Merged revisions 55795-55816 via svnmerge from
Guido van Rossum <guido@python.org>
parents:
41824
diff
changeset
|
194 if isinstance(etype, type): |
|
29511
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
195 etype = etype.__name__ |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
196 pyver = 'Python ' + sys.version.split()[0] + ': ' + sys.executable |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
197 date = time.ctime(time.time()) |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
198 head = "%s\n%s\n%s\n" % (str(etype), pyver, date) + ''' |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
199 A problem occurred in a Python script. Here is the sequence of |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
200 function calls leading up to the error, in the order they occurred. |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
201 ''' |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
202 |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
203 frames = [] |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
204 records = inspect.getinnerframes(etb, context) |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
205 for frame, file, lnum, func, lines, index in records: |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
206 file = file and os.path.abspath(file) or '?' |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
207 args, varargs, varkw, locals = inspect.getargvalues(frame) |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
208 call = '' |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
209 if func != '?': |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
210 call = 'in ' + func + \ |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
211 inspect.formatargvalues(args, varargs, varkw, locals, |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
212 formatvalue=lambda value: '=' + pydoc.text.repr(value)) |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
213 |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
214 highlight = {} |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
215 def reader(lnum=[lnum]): |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
216 highlight[lnum[0]] = 1 |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
217 try: return linecache.getline(file, lnum[0]) |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
218 finally: lnum[0] += 1 |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
219 vars = scanvars(reader, frame, locals) |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
220 |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
221 rows = [' %s %s' % (file, call)] |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
222 if index is not None: |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
223 i = lnum - index |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
224 for line in lines: |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
225 num = '%5d ' % i |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
226 rows.append(num+line.rstrip()) |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
227 i += 1 |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
228 |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
229 done, dump = {}, [] |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
230 for name, where, value in vars: |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
231 if name in done: continue |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
232 done[name] = 1 |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
233 if value is not __UNDEF__: |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
234 if where == 'global': name = 'global ' + name |
|
32292
e1345ce275f7
Another nit found by Neal Norwitz using pychecker. This was caused by a
Skip Montanaro <skip@pobox.com>
parents:
32263
diff
changeset
|
235 elif where != 'local': name = where + name.split('.')[-1] |
|
29511
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
236 dump.append('%s = %s' % (name, pydoc.text.repr(value))) |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
237 else: |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
238 dump.append(name + ' undefined') |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
239 |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
240 rows.append('\n'.join(dump)) |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
241 frames.append('\n%s\n' % '\n'.join(rows)) |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
242 |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
243 exception = ['%s: %s' % (str(etype), str(evalue))] |
|
41437
3667d1a8c916
Bug #1697782: remove all remaining code that uses types.InstanceType.
Georg Brandl <georg@python.org>
parents:
35742
diff
changeset
|
244 for name in dir(evalue): |
|
3667d1a8c916
Bug #1697782: remove all remaining code that uses types.InstanceType.
Georg Brandl <georg@python.org>
parents:
35742
diff
changeset
|
245 value = pydoc.text.repr(getattr(evalue, name)) |
|
3667d1a8c916
Bug #1697782: remove all remaining code that uses types.InstanceType.
Georg Brandl <georg@python.org>
parents:
35742
diff
changeset
|
246 exception.append('\n%s%s = %s' % (" "*4, name, value)) |
|
29511
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
247 |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
248 return head + ''.join(frames) + ''.join(exception) + ''' |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
249 |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
250 The above is a description of an error in a Python program. Here is |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
251 the original traceback: |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
252 |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
253 %s |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
254 ''' % ''.join(traceback.format_exception(etype, evalue, etb)) |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
255 |
| 19365 | 256 class Hook: |
| 19421 | 257 """A hook to replace sys.excepthook that shows tracebacks in HTML.""" |
| 258 | |
|
29511
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
259 def __init__(self, display=1, logdir=None, context=5, file=None, |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
260 format="html"): |
| 19365 | 261 self.display = display # send tracebacks to browser if true |
| 262 self.logdir = logdir # log tracebacks to files if not None | |
| 19421 | 263 self.context = context # number of source code lines per frame |
|
21194
1519d6faab15
Add "file" argument to Hook constructor.
Ka-Ping Yee <ping@zesty.ca>
parents:
19421
diff
changeset
|
264 self.file = file or sys.stdout # place to send the output |
|
29511
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
265 self.format = format |
| 19365 | 266 |
| 267 def __call__(self, etype, evalue, etb): | |
| 268 self.handle((etype, evalue, etb)) | |
| 269 | |
| 270 def handle(self, info=None): | |
| 271 info = info or sys.exc_info() | |
|
29511
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
272 if self.format == "html": |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
273 self.file.write(reset()) |
| 19365 | 274 |
|
29511
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
275 formatter = (self.format=="html") and html or text |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
276 plain = False |
| 19365 | 277 try: |
|
29511
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
278 doc = formatter(info, self.context) |
| 19365 | 279 except: # just in case something goes wrong |
|
29511
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
280 doc = ''.join(traceback.format_exception(*info)) |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
281 plain = True |
| 19365 | 282 |
| 283 if self.display: | |
|
29511
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
284 if plain: |
| 19365 | 285 doc = doc.replace('&', '&').replace('<', '<') |
|
21194
1519d6faab15
Add "file" argument to Hook constructor.
Ka-Ping Yee <ping@zesty.ca>
parents:
19421
diff
changeset
|
286 self.file.write('<pre>' + doc + '</pre>\n') |
| 19365 | 287 else: |
|
21194
1519d6faab15
Add "file" argument to Hook constructor.
Ka-Ping Yee <ping@zesty.ca>
parents:
19421
diff
changeset
|
288 self.file.write(doc + '\n') |
| 19365 | 289 else: |
|
21194
1519d6faab15
Add "file" argument to Hook constructor.
Ka-Ping Yee <ping@zesty.ca>
parents:
19421
diff
changeset
|
290 self.file.write('<p>A problem occurred in a Python script.\n') |
| 19365 | 291 |
| 292 if self.logdir is not None: | |
|
32001
2cc714977479
[Bug #945063] Get file extension correct. (2.3 bugfix candidate)
Andrew M. Kuchling <amk@amk.ca>
parents:
31850
diff
changeset
|
293 suffix = ['.txt', '.html'][self.format=="html"] |
|
29511
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
294 (fd, path) = tempfile.mkstemp(suffix=suffix, dir=self.logdir) |
|
79972
abbfb89055d3
#12890: don't emit <p> tags in text mode when logdir specified.
R David Murray <rdmurray@bitdance.com>
parents:
53072
diff
changeset
|
295 |
| 19365 | 296 try: |
|
24710
11c701038805
Massive changes from SF 589982 (tempfile.py rewrite, by Zack
Guido van Rossum <guido@python.org>
parents:
23998
diff
changeset
|
297 file = os.fdopen(fd, 'w') |
| 19365 | 298 file.write(doc) |
| 299 file.close() | |
|
79972
abbfb89055d3
#12890: don't emit <p> tags in text mode when logdir specified.
R David Murray <rdmurray@bitdance.com>
parents:
53072
diff
changeset
|
300 msg = '%s contains the description of this error.' % path |
| 19365 | 301 except: |
|
79972
abbfb89055d3
#12890: don't emit <p> tags in text mode when logdir specified.
R David Murray <rdmurray@bitdance.com>
parents:
53072
diff
changeset
|
302 msg = 'Tried to save traceback to %s, but failed.' % path |
|
abbfb89055d3
#12890: don't emit <p> tags in text mode when logdir specified.
R David Murray <rdmurray@bitdance.com>
parents:
53072
diff
changeset
|
303 |
|
abbfb89055d3
#12890: don't emit <p> tags in text mode when logdir specified.
R David Murray <rdmurray@bitdance.com>
parents:
53072
diff
changeset
|
304 if self.format == 'html': |
|
abbfb89055d3
#12890: don't emit <p> tags in text mode when logdir specified.
R David Murray <rdmurray@bitdance.com>
parents:
53072
diff
changeset
|
305 self.file.write('<p>%s</p>\n' % msg) |
|
abbfb89055d3
#12890: don't emit <p> tags in text mode when logdir specified.
R David Murray <rdmurray@bitdance.com>
parents:
53072
diff
changeset
|
306 else: |
|
abbfb89055d3
#12890: don't emit <p> tags in text mode when logdir specified.
R David Murray <rdmurray@bitdance.com>
parents:
53072
diff
changeset
|
307 self.file.write(msg + '\n') |
|
21194
1519d6faab15
Add "file" argument to Hook constructor.
Ka-Ping Yee <ping@zesty.ca>
parents:
19421
diff
changeset
|
308 try: |
|
1519d6faab15
Add "file" argument to Hook constructor.
Ka-Ping Yee <ping@zesty.ca>
parents:
19421
diff
changeset
|
309 self.file.flush() |
|
1519d6faab15
Add "file" argument to Hook constructor.
Ka-Ping Yee <ping@zesty.ca>
parents:
19421
diff
changeset
|
310 except: pass |
| 19365 | 311 |
| 312 handler = Hook().handle | |
|
29511
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
313 def enable(display=1, logdir=None, context=5, format="html"): |
| 19421 | 314 """Install an exception handler that formats tracebacks as HTML. |
| 315 | |
| 316 The optional argument 'display' can be set to 0 to suppress sending the | |
| 317 traceback to the browser, and 'logdir' can be set to a directory to cause | |
| 318 tracebacks to be written to files there.""" | |
|
29511
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
319 sys.excepthook = Hook(display=display, logdir=logdir, |
|
d1acf89d1c49
SF Patch 569574 - enhancements to cgitb for plain text display
Skip Montanaro <skip@pobox.com>
parents:
26912
diff
changeset
|
320 context=context, format=format) |
