From 991f9202bede42b033e499525755daed4a1c07be Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Tue, 5 May 2009 08:31:54 +0000 Subject: Merged revisions 72319-72320 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r72319 | georg.brandl | 2009-05-05 10:28:49 +0200 (Di, 05 Mai 2009) | 1 line #1309567: fix linecache behavior of stripping subdirectories from paths when looking for relative filename matches. Also add a linecache test suite. ........ r72320 | georg.brandl | 2009-05-05 10:30:28 +0200 (Di, 05 Mai 2009) | 1 line Add a news entry for r72319. ........ --- Lib/linecache.py | 7 ++- Lib/test/test_linecache.py | 129 +++++++++++++++++++++++++++++++++++++++++++++ Misc/NEWS | 3 ++ 3 files changed, 137 insertions(+), 2 deletions(-) create mode 100644 Lib/test/test_linecache.py diff --git a/Lib/linecache.py b/Lib/linecache.py index 51404e2..27883fde 100644 --- a/Lib/linecache.py +++ b/Lib/linecache.py @@ -80,7 +80,7 @@ def updatecache(filename, module_globals=None): try: stat = os.stat(fullname) except os.error as msg: - basename = os.path.split(filename)[1] + basename = filename # Try for a __loader__, if available if module_globals and '__loader__' in module_globals: @@ -104,7 +104,10 @@ def updatecache(filename, module_globals=None): ) return cache[filename][2] - # Try looking through the module search path. + # Try looking through the module search path, which is only useful + # when handling a relative filename. + if os.path.isabs(filename): + return [] for dirname in sys.path: try: diff --git a/Lib/test/test_linecache.py b/Lib/test/test_linecache.py new file mode 100644 index 0000000..14d8d59 --- /dev/null +++ b/Lib/test/test_linecache.py @@ -0,0 +1,129 @@ +""" Tests for the linecache module """ + +import linecache +import unittest +import os.path +from test import support + + +FILENAME = linecache.__file__ +INVALID_NAME = '!@$)(!@#_1' +EMPTY = '' +TESTS = 'cjkencodings_test inspect_fodder inspect_fodder2 mapping_tests' +TESTS = TESTS.split() +TEST_PATH = os.path.dirname(support.__file__) +MODULES = "linecache unittest".split() +MODULE_PATH = os.path.dirname(FILENAME) + +SOURCE_1 = ''' +" Docstring " + +def function(): + return result + +''' + +SOURCE_2 = ''' +def f(): + return 1 + 1 + +a = f() + +''' + +class LineCacheTests(unittest.TestCase): + + def test_getline(self): + getline = linecache.getline + + # Bad values for line number should return an empty string + self.assertEquals(getline(FILENAME, 2**15), EMPTY) + self.assertEquals(getline(FILENAME, -1), EMPTY) + + # Float values currently raise TypeError, should it? + self.assertRaises(TypeError, getline, FILENAME, 1.1) + + # Bad filenames should return an empty string + self.assertEquals(getline(EMPTY, 1), EMPTY) + self.assertEquals(getline(INVALID_NAME, 1), EMPTY) + + # Check whether lines correspond to those from file iteration + for entry in TESTS: + filename = os.path.join(TEST_PATH, entry) + '.py' + for index, line in enumerate(open(filename)): + self.assertEquals(line, getline(filename, index + 1)) + + # Check module loading + for entry in MODULES: + filename = os.path.join(MODULE_PATH, entry) + '.py' + for index, line in enumerate(open(filename)): + self.assertEquals(line, getline(filename, index + 1)) + + # Check that bogus data isn't returned (issue #1309567) + empty = linecache.getlines('a/b/c/__init__.py') + self.assertEquals(empty, []) + + def test_clearcache(self): + cached = [] + for entry in TESTS: + filename = os.path.join(TEST_PATH, entry) + '.py' + cached.append(filename) + linecache.getline(filename, 1) + + # Are all files cached? + cached_empty = [fn for fn in cached if fn not in linecache.cache] + self.assertEquals(cached_empty, []) + + # Can we clear the cache? + linecache.clearcache() + cached_empty = [fn for fn in cached if fn in linecache.cache] + self.assertEquals(cached_empty, []) + + def test_checkcache(self): + getline = linecache.getline + try: + # Create a source file and cache its contents + source_name = os.path.join(TEST_PATH, 'linecache_test.py') + source = open(source_name, 'w') + source.write(SOURCE_1) + source.close() + getline(source_name, 1) + + # Keep a copy of the old contents + source_list = [] + source = open(source_name) + for index, line in enumerate(source): + self.assertEquals(line, getline(source_name, index + 1)) + source_list.append(line) + source.close() + + source = open(source_name, 'w') + source.write(SOURCE_2) + source.close() + + # Try to update a bogus cache entry + linecache.checkcache('dummy') + + # Check that the cache matches the old contents + for index, line in enumerate(source_list): + self.assertEquals(line, getline(source_name, index + 1)) + + # Update the cache and check whether it matches the new source file + linecache.checkcache(source_name) + source = open(source_name) + for index, line in enumerate(source): + self.assertEquals(line, getline(source_name, index + 1)) + source_list.append(line) + source.close() + + finally: + try: + source.close() + finally: + support.unlink(source_name) + +def test_main(): + support.run_unittest(LineCacheTests) + +if __name__ == "__main__": + test_main() diff --git a/Misc/NEWS b/Misc/NEWS index 5b4f0ab..8edd845 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -118,6 +118,9 @@ Installation Library ------- +- Issue #1309567: Fix linecache behavior of stripping subdirectories when + looking for files given by a relative filename. + - Issue #5923: Update the ``turtle`` module to version 1.1, add two new turtle demos in Demo/turtle. -- cgit v0.12