Commit 1c431d7d authored by Hye-Shik Chang's avatar Hye-Shik Chang

SF #737473: Show up-to-date source code in tracebacks always.

And add an optional argument 'filename' to linecache.checkcache()
to enable checking caches per-file.
parent d379e8cf
...@@ -31,9 +31,10 @@ Clear the cache. Use this function if you no longer need lines from ...@@ -31,9 +31,10 @@ Clear the cache. Use this function if you no longer need lines from
files previously read using \function{getline()}. files previously read using \function{getline()}.
\end{funcdesc} \end{funcdesc}
\begin{funcdesc}{checkcache}{} \begin{funcdesc}{checkcache}{\optional{filename}}
Check the cache for validity. Use this function if files in the cache Check the cache for validity. Use this function if files in the cache
may have changed on disk, and you require the updated version. may have changed on disk, and you require the updated version. If
\var{filename} is omitted, it will check the whole cache entries.
\end{funcdesc} \end{funcdesc}
Example: Example:
......
...@@ -40,11 +40,19 @@ def getlines(filename): ...@@ -40,11 +40,19 @@ def getlines(filename):
return updatecache(filename) return updatecache(filename)
def checkcache(): def checkcache(filename=None):
"""Discard cache entries that are out of date. """Discard cache entries that are out of date.
(This is not checked upon each call!)""" (This is not checked upon each call!)"""
for filename in cache.keys(): if filename is None:
filenames = cache.keys()
else:
if filename in cache:
filenames = [filename]
else:
return
for filename in filenames:
size, mtime, lines, fullname = cache[filename] size, mtime, lines, fullname = cache[filename]
try: try:
stat = os.stat(fullname) stat = os.stat(fullname)
......
...@@ -40,6 +40,47 @@ class TracebackCases(unittest.TestCase): ...@@ -40,6 +40,47 @@ class TracebackCases(unittest.TestCase):
self.assert_(len(err) == 3) self.assert_(len(err) == 3)
self.assert_(err[1].strip() == "[x for x in x] = x") self.assert_(err[1].strip() == "[x for x in x] = x")
def test_bug737473(self):
import sys, os, tempfile
savedpath = sys.path[:]
testdir = tempfile.mkdtemp()
try:
sys.path.insert(0, testdir)
testfile = os.path.join(testdir, 'test_bug737473.py')
print >> open(testfile, 'w'), """\
def test():
raise ValueError"""
if hasattr(os, 'utime'):
os.utime(testfile, (0, 0))
else:
import time
time.sleep(3) # not to stay in same mtime.
if 'test_bug737473' in sys.modules:
del sys.modules['test_bug737473']
import test_bug737473
try:
test_bug737473.test()
except ValueError:
# this loads source code to linecache
traceback.extract_tb(sys.exc_traceback)
print >> open(testfile, 'w'), """\
def test():
raise NotImplementedError"""
reload(test_bug737473)
try:
test_bug737473.test()
except NotImplementedError:
src = traceback.extract_tb(sys.exc_traceback)[-1][-1]
self.failUnlessEqual(src, 'raise NotImplementedError')
finally:
sys.path[:] = savedpath
for f in os.listdir(testdir):
os.unlink(os.path.join(testdir, f))
os.rmdir(testdir)
def test_main(): def test_main():
run_unittest(TracebackCases) run_unittest(TracebackCases)
......
...@@ -65,6 +65,7 @@ def print_tb(tb, limit=None, file=None): ...@@ -65,6 +65,7 @@ def print_tb(tb, limit=None, file=None):
name = co.co_name name = co.co_name
_print(file, _print(file,
' File "%s", line %d, in %s' % (filename,lineno,name)) ' File "%s", line %d, in %s' % (filename,lineno,name))
linecache.checkcache(filename)
line = linecache.getline(filename, lineno) line = linecache.getline(filename, lineno)
if line: _print(file, ' ' + line.strip()) if line: _print(file, ' ' + line.strip())
tb = tb.tb_next tb = tb.tb_next
...@@ -96,6 +97,7 @@ def extract_tb(tb, limit = None): ...@@ -96,6 +97,7 @@ def extract_tb(tb, limit = None):
co = f.f_code co = f.f_code
filename = co.co_filename filename = co.co_filename
name = co.co_name name = co.co_name
linecache.checkcache(filename)
line = linecache.getline(filename, lineno) line = linecache.getline(filename, lineno)
if line: line = line.strip() if line: line = line.strip()
else: line = None else: line = None
...@@ -277,6 +279,7 @@ def extract_stack(f=None, limit = None): ...@@ -277,6 +279,7 @@ def extract_stack(f=None, limit = None):
co = f.f_code co = f.f_code
filename = co.co_filename filename = co.co_filename
name = co.co_name name = co.co_name
linecache.checkcache(filename)
line = linecache.getline(filename, lineno) line = linecache.getline(filename, lineno)
if line: line = line.strip() if line: line = line.strip()
else: line = None else: line = None
......
...@@ -59,6 +59,9 @@ Library ...@@ -59,6 +59,9 @@ Library
- Bug #1017553: fix bug in tarfile.filemode() - Bug #1017553: fix bug in tarfile.filemode()
- Bug #737473: fix bug that old source code is shown in tracebacks even if
the source code is updated and reloaded.
Build Build
----- -----
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment