summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorHye-Shik Chang <hyeshik@gmail.com>2004-10-26 09:16:42 (GMT)
committerHye-Shik Chang <hyeshik@gmail.com>2004-10-26 09:16:42 (GMT)
commit182ac8514726402451a90fd59c9bf427f8071365 (patch)
tree1e7d6a1c24390a303d69842271d0a96cabefba7b /Lib
parent23109ef11e91c49b56b517ce454bcf87a4153c62 (diff)
downloadcpython-182ac8514726402451a90fd59c9bf427f8071365.zip
cpython-182ac8514726402451a90fd59c9bf427f8071365.tar.gz
cpython-182ac8514726402451a90fd59c9bf427f8071365.tar.bz2
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.
Diffstat (limited to 'Lib')
-rw-r--r--Lib/linecache.py12
-rw-r--r--Lib/test/test_traceback.py41
-rw-r--r--Lib/traceback.py3
3 files changed, 54 insertions, 2 deletions
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