summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/lib/liblinecache.tex5
-rw-r--r--Lib/linecache.py12
-rw-r--r--Lib/test/test_traceback.py41
-rw-r--r--Lib/traceback.py3
-rw-r--r--Misc/NEWS3
5 files changed, 60 insertions, 4 deletions
diff --git a/Doc/lib/liblinecache.tex b/Doc/lib/liblinecache.tex
index 8a9b914..c022ba9 100644
--- a/Doc/lib/liblinecache.tex
+++ b/Doc/lib/liblinecache.tex
@@ -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:
diff --git a/Lib/linecache.py b/Lib/linecache.py
index 1b70c7c..2ccc6c6 100644
--- a/Lib/linecache.py
+++ b/Lib/linecache.py
@@ -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)
diff --git a/Lib/test/test_traceback.py b/Lib/test/test_traceback.py
index dc22c75..6812095 100644
--- a/Lib/test/test_traceback.py
+++ b/Lib/test/test_traceback.py
@@ -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)
diff --git a/Lib/traceback.py b/Lib/traceback.py
index cf78648..95cde2b 100644
--- a/Lib/traceback.py
+++ b/Lib/traceback.py
@@ -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
diff --git a/Misc/NEWS b/Misc/NEWS
index 6c0935e..59c3ef6 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -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
-----