1""" Tests for the linecache module """ 2 3import linecache 4import unittest 5import os.path 6from test import test_support as support 7 8 9FILENAME = linecache.__file__ 10INVALID_NAME = '!@$)(!@#_1' 11EMPTY = '' 12TESTS = 'inspect_fodder inspect_fodder2 mapping_tests' 13TESTS = TESTS.split() 14TEST_PATH = os.path.dirname(support.__file__) 15MODULES = "linecache abc".split() 16MODULE_PATH = os.path.dirname(FILENAME) 17 18SOURCE_1 = ''' 19" Docstring " 20 21def function(): 22 return result 23 24''' 25 26SOURCE_2 = ''' 27def f(): 28 return 1 + 1 29 30a = f() 31 32''' 33 34SOURCE_3 = ''' 35def f(): 36 return 3''' # No ending newline 37 38 39class LineCacheTests(unittest.TestCase): 40 41 def test_getline(self): 42 getline = linecache.getline 43 44 # Bad values for line number should return an empty string 45 self.assertEqual(getline(FILENAME, 2**15), EMPTY) 46 self.assertEqual(getline(FILENAME, -1), EMPTY) 47 48 # Float values currently raise TypeError, should it? 49 self.assertRaises(TypeError, getline, FILENAME, 1.1) 50 51 # Bad filenames should return an empty string 52 self.assertEqual(getline(EMPTY, 1), EMPTY) 53 self.assertEqual(getline(INVALID_NAME, 1), EMPTY) 54 55 # Check whether lines correspond to those from file iteration 56 for entry in TESTS: 57 filename = os.path.join(TEST_PATH, entry) + '.py' 58 for index, line in enumerate(open(filename)): 59 self.assertEqual(line, getline(filename, index + 1)) 60 61 # Check module loading 62 for entry in MODULES: 63 filename = os.path.join(MODULE_PATH, entry) + '.py' 64 for index, line in enumerate(open(filename)): 65 self.assertEqual(line, getline(filename, index + 1)) 66 67 # Check that bogus data isn't returned (issue #1309567) 68 empty = linecache.getlines('a/b/c/__init__.py') 69 self.assertEqual(empty, []) 70 71 def test_no_ending_newline(self): 72 self.addCleanup(support.unlink, support.TESTFN) 73 with open(support.TESTFN, "w") as fp: 74 fp.write(SOURCE_3) 75 lines = linecache.getlines(support.TESTFN) 76 self.assertEqual(lines, ["\n", "def f():\n", " return 3\n"]) 77 78 def test_clearcache(self): 79 cached = [] 80 for entry in TESTS: 81 filename = os.path.join(TEST_PATH, entry) + '.py' 82 cached.append(filename) 83 linecache.getline(filename, 1) 84 85 # Are all files cached? 86 cached_empty = [fn for fn in cached if fn not in linecache.cache] 87 self.assertEqual(cached_empty, []) 88 89 # Can we clear the cache? 90 linecache.clearcache() 91 cached_empty = [fn for fn in cached if fn in linecache.cache] 92 self.assertEqual(cached_empty, []) 93 94 def test_checkcache(self): 95 getline = linecache.getline 96 # Create a source file and cache its contents 97 source_name = support.TESTFN + '.py' 98 self.addCleanup(support.unlink, source_name) 99 with open(source_name, 'w') as source: 100 source.write(SOURCE_1) 101 getline(source_name, 1) 102 103 # Keep a copy of the old contents 104 source_list = [] 105 with open(source_name) as source: 106 for index, line in enumerate(source): 107 self.assertEqual(line, getline(source_name, index + 1)) 108 source_list.append(line) 109 110 with open(source_name, 'w') as source: 111 source.write(SOURCE_2) 112 113 # Try to update a bogus cache entry 114 linecache.checkcache('dummy') 115 116 # Check that the cache matches the old contents 117 for index, line in enumerate(source_list): 118 self.assertEqual(line, getline(source_name, index + 1)) 119 120 # Update the cache and check whether it matches the new source file 121 linecache.checkcache(source_name) 122 with open(source_name) as source: 123 for index, line in enumerate(source): 124 self.assertEqual(line, getline(source_name, index + 1)) 125 source_list.append(line) 126 127 def test_memoryerror(self): 128 lines = linecache.getlines(FILENAME) 129 self.assertTrue(lines) 130 def raise_memoryerror(*args, **kwargs): 131 raise MemoryError 132 with support.swap_attr(linecache, 'updatecache', raise_memoryerror): 133 lines2 = linecache.getlines(FILENAME) 134 self.assertEqual(lines2, lines) 135 136 linecache.clearcache() 137 with support.swap_attr(linecache, 'updatecache', raise_memoryerror): 138 lines3 = linecache.getlines(FILENAME) 139 self.assertEqual(lines3, []) 140 self.assertEqual(linecache.getlines(FILENAME), lines) 141 142 143def test_main(): 144 support.run_unittest(LineCacheTests) 145 146if __name__ == "__main__": 147 test_main() 148