From: Serhiy Storchaka Date: Wed, 1 Apr 2015 13:56:13 +0000 (+0300) Subject: Issue #23838: linecache now clears the cache and returns an empty result on X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=05ddbf0875b449f69616c31fbbe49dd5f3d5e329;p=python Issue #23838: linecache now clears the cache and returns an empty result on MemoryError. --- 05ddbf0875b449f69616c31fbbe49dd5f3d5e329 diff --cc Lib/linecache.py index 6e65c37e13,884cbf493a..3afcce1f0a --- a/Lib/linecache.py +++ b/Lib/linecache.py @@@ -39,12 -36,13 +39,15 @@@ def getlines(filename, module_globals=N Update the cache if it doesn't contain an entry for this file already.""" if filename in cache: - return cache[filename][2] + entry = cache[filename] - if len(entry) == 1: - return updatecache(filename, module_globals) - return cache[filename][2] - else: ++ if len(entry) != 1: ++ return cache[filename][2] + + try: return updatecache(filename, module_globals) + except MemoryError: + clearcache() + return [] def checkcache(filename=None): diff --cc Lib/test/test_linecache.py index 2fb86626f7,79157de43f..21ef738932 --- a/Lib/test/test_linecache.py +++ b/Lib/test/test_linecache.py @@@ -127,51 -126,21 +127,63 @@@ class LineCacheTests(unittest.TestCase) self.assertEqual(line, getline(source_name, index + 1)) source_list.append(line) + def test_lazycache_no_globals(self): + lines = linecache.getlines(FILENAME) + linecache.clearcache() + self.assertEqual(False, linecache.lazycache(FILENAME, None)) + self.assertEqual(lines, linecache.getlines(FILENAME)) + + def test_lazycache_smoke(self): + lines = linecache.getlines(NONEXISTENT_FILENAME, globals()) + linecache.clearcache() + self.assertEqual( + True, linecache.lazycache(NONEXISTENT_FILENAME, globals())) + self.assertEqual(1, len(linecache.cache[NONEXISTENT_FILENAME])) + # Note here that we're looking up a non existant filename with no + # globals: this would error if the lazy value wasn't resolved. + self.assertEqual(lines, linecache.getlines(NONEXISTENT_FILENAME)) + + def test_lazycache_provide_after_failed_lookup(self): + linecache.clearcache() + lines = linecache.getlines(NONEXISTENT_FILENAME, globals()) + linecache.clearcache() + linecache.getlines(NONEXISTENT_FILENAME) + linecache.lazycache(NONEXISTENT_FILENAME, globals()) + self.assertEqual(lines, linecache.updatecache(NONEXISTENT_FILENAME)) + + def test_lazycache_check(self): + linecache.clearcache() + linecache.lazycache(NONEXISTENT_FILENAME, globals()) + linecache.checkcache() + + def test_lazycache_bad_filename(self): + linecache.clearcache() + self.assertEqual(False, linecache.lazycache('', globals())) + self.assertEqual(False, linecache.lazycache('', globals())) + + def test_lazycache_already_cached(self): + linecache.clearcache() + lines = linecache.getlines(NONEXISTENT_FILENAME, globals()) + self.assertEqual( + False, + linecache.lazycache(NONEXISTENT_FILENAME, globals())) + self.assertEqual(4, len(linecache.cache[NONEXISTENT_FILENAME])) + + def test_memoryerror(self): + lines = linecache.getlines(FILENAME) + self.assertTrue(lines) + def raise_memoryerror(*args, **kwargs): + raise MemoryError + with support.swap_attr(linecache, 'updatecache', raise_memoryerror): + lines2 = linecache.getlines(FILENAME) + self.assertEqual(lines2, lines) + + linecache.clearcache() + with support.swap_attr(linecache, 'updatecache', raise_memoryerror): + lines3 = linecache.getlines(FILENAME) + self.assertEqual(lines3, []) + self.assertEqual(linecache.getlines(FILENAME), lines) - def test_main(): - support.run_unittest(LineCacheTests) if __name__ == "__main__": - test_main() + unittest.main() diff --cc Misc/NEWS index 6b63fdc553,58cdebdee2..b34da3ad0c --- a/Misc/NEWS +++ b/Misc/NEWS @@@ -13,14 -13,17 +13,17 @@@ Core and Builtin Library ------- + - Issue #23838: linecache now clears the cache and returns an empty result on + MemoryError. + +- Issue #10395: Added os.path.commonpath(). Implemented in posixpath and ntpath. + Based on patch by Rafik Draoui. + +- Issue #23611: Serializing more "lookupable" objects (such as unbound methods + or nested classes) now are supported with pickle protocols < 4. + +- Issue #13583: sqlite3.Row now supports slice indexing. + - Issue #18473: Fixed 2to3 and 3to2 compatible pickle mappings. Fixed ambigious reverse mappings. Added many new mappings. Import mapping is no longer applied to modules already mapped with full name mapping.