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.
This commit is contained in:
Hye-Shik Chang 2004-10-26 09:16:42 +00:00
parent 23109ef11e
commit 182ac85147
5 changed files with 60 additions and 4 deletions

View File

@ -31,9 +31,10 @@ Clear the cache. Use this function if you no longer need lines from
files previously read using \function{getline()}.
\end{funcdesc}
\begin{funcdesc}{checkcache}{}
\begin{funcdesc}{checkcache}{\optional{filename}}
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}
Example:

View File

@ -40,11 +40,19 @@ def getlines(filename):
return updatecache(filename)
def checkcache():
def checkcache(filename=None):
"""Discard cache entries that are out of date.
(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]
try:
stat = os.stat(fullname)

View File

@ -40,6 +40,47 @@ class TracebackCases(unittest.TestCase):
self.assert_(len(err) == 3)
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():
run_unittest(TracebackCases)

View File

@ -65,6 +65,7 @@ def print_tb(tb, limit=None, file=None):
name = co.co_name
_print(file,
' File "%s", line %d, in %s' % (filename,lineno,name))
linecache.checkcache(filename)
line = linecache.getline(filename, lineno)
if line: _print(file, ' ' + line.strip())
tb = tb.tb_next
@ -96,6 +97,7 @@ def extract_tb(tb, limit = None):
co = f.f_code
filename = co.co_filename
name = co.co_name
linecache.checkcache(filename)
line = linecache.getline(filename, lineno)
if line: line = line.strip()
else: line = None
@ -277,6 +279,7 @@ def extract_stack(f=None, limit = None):
co = f.f_code
filename = co.co_filename
name = co.co_name
linecache.checkcache(filename)
line = linecache.getline(filename, lineno)
if line: line = line.strip()
else: line = None

View File

@ -59,6 +59,9 @@ Library
- 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
-----