blob: 47e2eddfb14d6bf8639faad7564088e616a14695 [file] [log] [blame]
Georg Brandl991f9202009-05-05 08:31:54 +00001""" Tests for the linecache module """
2
3import linecache
4import unittest
5import os.path
6from test import support
7
8
9FILENAME = linecache.__file__
Robert Collins6bc2c1e2015-03-05 12:07:57 +130010NONEXISTENT_FILENAME = FILENAME + '.missing'
Georg Brandl991f9202009-05-05 08:31:54 +000011INVALID_NAME = '!@$)(!@#_1'
12EMPTY = ''
Victor Stinnere98f1772011-05-16 17:18:51 +020013TESTS = 'inspect_fodder inspect_fodder2 mapping_tests'
Georg Brandl991f9202009-05-05 08:31:54 +000014TESTS = TESTS.split()
Nick Coghlanfb15aa12013-07-28 20:56:19 +100015TEST_PATH = os.path.dirname(__file__)
Benjamin Petersonbed7d042009-07-19 21:01:52 +000016MODULES = "linecache abc".split()
Georg Brandl991f9202009-05-05 08:31:54 +000017MODULE_PATH = os.path.dirname(FILENAME)
18
19SOURCE_1 = '''
20" Docstring "
21
22def function():
23 return result
24
25'''
26
27SOURCE_2 = '''
28def f():
29 return 1 + 1
30
31a = f()
32
33'''
34
Benjamin Petersonaada7b82010-05-21 21:45:06 +000035SOURCE_3 = '''
36def f():
37 return 3''' # No ending newline
38
39
Georg Brandl991f9202009-05-05 08:31:54 +000040class LineCacheTests(unittest.TestCase):
41
42 def test_getline(self):
43 getline = linecache.getline
44
45 # Bad values for line number should return an empty string
Ezio Melottib3aedd42010-11-20 19:04:17 +000046 self.assertEqual(getline(FILENAME, 2**15), EMPTY)
47 self.assertEqual(getline(FILENAME, -1), EMPTY)
Georg Brandl991f9202009-05-05 08:31:54 +000048
49 # Float values currently raise TypeError, should it?
50 self.assertRaises(TypeError, getline, FILENAME, 1.1)
51
52 # Bad filenames should return an empty string
Ezio Melottib3aedd42010-11-20 19:04:17 +000053 self.assertEqual(getline(EMPTY, 1), EMPTY)
54 self.assertEqual(getline(INVALID_NAME, 1), EMPTY)
Georg Brandl991f9202009-05-05 08:31:54 +000055
56 # Check whether lines correspond to those from file iteration
57 for entry in TESTS:
58 filename = os.path.join(TEST_PATH, entry) + '.py'
Brett Cannon01743682010-10-29 23:55:51 +000059 with open(filename) as file:
60 for index, line in enumerate(file):
Ezio Melottib3aedd42010-11-20 19:04:17 +000061 self.assertEqual(line, getline(filename, index + 1))
Georg Brandl991f9202009-05-05 08:31:54 +000062
63 # Check module loading
64 for entry in MODULES:
65 filename = os.path.join(MODULE_PATH, entry) + '.py'
Brett Cannon01743682010-10-29 23:55:51 +000066 with open(filename) as file:
67 for index, line in enumerate(file):
Ezio Melottib3aedd42010-11-20 19:04:17 +000068 self.assertEqual(line, getline(filename, index + 1))
Georg Brandl991f9202009-05-05 08:31:54 +000069
70 # Check that bogus data isn't returned (issue #1309567)
71 empty = linecache.getlines('a/b/c/__init__.py')
Ezio Melottib3aedd42010-11-20 19:04:17 +000072 self.assertEqual(empty, [])
Georg Brandl991f9202009-05-05 08:31:54 +000073
Benjamin Petersonaada7b82010-05-21 21:45:06 +000074 def test_no_ending_newline(self):
75 self.addCleanup(support.unlink, support.TESTFN)
76 with open(support.TESTFN, "w") as fp:
77 fp.write(SOURCE_3)
78 lines = linecache.getlines(support.TESTFN)
79 self.assertEqual(lines, ["\n", "def f():\n", " return 3\n"])
80
Georg Brandl991f9202009-05-05 08:31:54 +000081 def test_clearcache(self):
82 cached = []
83 for entry in TESTS:
84 filename = os.path.join(TEST_PATH, entry) + '.py'
85 cached.append(filename)
86 linecache.getline(filename, 1)
87
88 # Are all files cached?
89 cached_empty = [fn for fn in cached if fn not in linecache.cache]
Ezio Melottib3aedd42010-11-20 19:04:17 +000090 self.assertEqual(cached_empty, [])
Georg Brandl991f9202009-05-05 08:31:54 +000091
92 # Can we clear the cache?
93 linecache.clearcache()
94 cached_empty = [fn for fn in cached if fn in linecache.cache]
Ezio Melottib3aedd42010-11-20 19:04:17 +000095 self.assertEqual(cached_empty, [])
Georg Brandl991f9202009-05-05 08:31:54 +000096
97 def test_checkcache(self):
98 getline = linecache.getline
Benjamin Petersonaada7b82010-05-21 21:45:06 +000099 # Create a source file and cache its contents
100 source_name = support.TESTFN + '.py'
101 self.addCleanup(support.unlink, source_name)
102 with open(source_name, 'w') as source:
103 source.write(SOURCE_1)
104 getline(source_name, 1)
Georg Brandl991f9202009-05-05 08:31:54 +0000105
Benjamin Petersonaada7b82010-05-21 21:45:06 +0000106 # Keep a copy of the old contents
107 source_list = []
108 with open(source_name) as source:
109 for index, line in enumerate(source):
Ezio Melottib3aedd42010-11-20 19:04:17 +0000110 self.assertEqual(line, getline(source_name, index + 1))
Benjamin Petersonaada7b82010-05-21 21:45:06 +0000111 source_list.append(line)
Georg Brandl991f9202009-05-05 08:31:54 +0000112
Benjamin Petersonaada7b82010-05-21 21:45:06 +0000113 with open(source_name, 'w') as source:
114 source.write(SOURCE_2)
Georg Brandl991f9202009-05-05 08:31:54 +0000115
Benjamin Petersonaada7b82010-05-21 21:45:06 +0000116 # Try to update a bogus cache entry
117 linecache.checkcache('dummy')
118
119 # Check that the cache matches the old contents
120 for index, line in enumerate(source_list):
Ezio Melottib3aedd42010-11-20 19:04:17 +0000121 self.assertEqual(line, getline(source_name, index + 1))
Benjamin Petersonaada7b82010-05-21 21:45:06 +0000122
123 # Update the cache and check whether it matches the new source file
124 linecache.checkcache(source_name)
125 with open(source_name) as source:
126 for index, line in enumerate(source):
Ezio Melottib3aedd42010-11-20 19:04:17 +0000127 self.assertEqual(line, getline(source_name, index + 1))
Benjamin Petersonaada7b82010-05-21 21:45:06 +0000128 source_list.append(line)
Georg Brandl991f9202009-05-05 08:31:54 +0000129
Robert Collins6bc2c1e2015-03-05 12:07:57 +1300130 def test_lazycache_no_globals(self):
131 lines = linecache.getlines(FILENAME)
132 linecache.clearcache()
133 self.assertEqual(False, linecache.lazycache(FILENAME, None))
134 self.assertEqual(lines, linecache.getlines(FILENAME))
135
136 def test_lazycache_smoke(self):
137 lines = linecache.getlines(NONEXISTENT_FILENAME, globals())
138 linecache.clearcache()
139 self.assertEqual(
140 True, linecache.lazycache(NONEXISTENT_FILENAME, globals()))
141 self.assertEqual(1, len(linecache.cache[NONEXISTENT_FILENAME]))
Martin Panter46f50722016-05-26 05:35:26 +0000142 # Note here that we're looking up a nonexistent filename with no
Robert Collins6bc2c1e2015-03-05 12:07:57 +1300143 # globals: this would error if the lazy value wasn't resolved.
144 self.assertEqual(lines, linecache.getlines(NONEXISTENT_FILENAME))
145
146 def test_lazycache_provide_after_failed_lookup(self):
147 linecache.clearcache()
148 lines = linecache.getlines(NONEXISTENT_FILENAME, globals())
149 linecache.clearcache()
150 linecache.getlines(NONEXISTENT_FILENAME)
151 linecache.lazycache(NONEXISTENT_FILENAME, globals())
152 self.assertEqual(lines, linecache.updatecache(NONEXISTENT_FILENAME))
153
154 def test_lazycache_check(self):
155 linecache.clearcache()
156 linecache.lazycache(NONEXISTENT_FILENAME, globals())
157 linecache.checkcache()
158
159 def test_lazycache_bad_filename(self):
160 linecache.clearcache()
161 self.assertEqual(False, linecache.lazycache('', globals()))
162 self.assertEqual(False, linecache.lazycache('<foo>', globals()))
163
164 def test_lazycache_already_cached(self):
165 linecache.clearcache()
166 lines = linecache.getlines(NONEXISTENT_FILENAME, globals())
167 self.assertEqual(
168 False,
169 linecache.lazycache(NONEXISTENT_FILENAME, globals()))
170 self.assertEqual(4, len(linecache.cache[NONEXISTENT_FILENAME]))
171
Serhiy Storchakac512adc2015-04-01 16:54:05 +0300172 def test_memoryerror(self):
173 lines = linecache.getlines(FILENAME)
174 self.assertTrue(lines)
175 def raise_memoryerror(*args, **kwargs):
176 raise MemoryError
177 with support.swap_attr(linecache, 'updatecache', raise_memoryerror):
178 lines2 = linecache.getlines(FILENAME)
179 self.assertEqual(lines2, lines)
Robert Collins6bc2c1e2015-03-05 12:07:57 +1300180
Serhiy Storchakac512adc2015-04-01 16:54:05 +0300181 linecache.clearcache()
182 with support.swap_attr(linecache, 'updatecache', raise_memoryerror):
183 lines3 = linecache.getlines(FILENAME)
184 self.assertEqual(lines3, [])
185 self.assertEqual(linecache.getlines(FILENAME), lines)
186
Georg Brandl991f9202009-05-05 08:31:54 +0000187
188if __name__ == "__main__":
Serhiy Storchakac512adc2015-04-01 16:54:05 +0300189 unittest.main()