]> granicus.if.org Git - python/commitdiff
Issue #23838: linecache now clears the cache and returns an empty result on
authorSerhiy Storchaka <storchaka@gmail.com>
Wed, 1 Apr 2015 13:56:13 +0000 (16:56 +0300)
committerSerhiy Storchaka <storchaka@gmail.com>
Wed, 1 Apr 2015 13:56:13 +0000 (16:56 +0300)
MemoryError.

1  2 
Lib/linecache.py
Lib/test/test_linecache.py
Misc/NEWS

index 6e65c37e1354c49ad8d84a3a2e5189138b9311b0,884cbf493a494da752d15c6a7b52d575fa7649a2..3afcce1f0a14566c67e97527e95f90afba89c07f
@@@ -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):
index 2fb86626f7ddac727f867c7289012dd28f531714,79157de43f6231240dc22fbc1ddd56a7cb053512..21ef738932596b5e73a645e659bda9d6785506f7
@@@ -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('<foo>', 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 6b63fdc55302c4682cdb6a629154172cfe78d7b0,58cdebdee26731d5c19ba69475a618037fd255c4..b34da3ad0cb94398edda49309615fc1dc4cb6bbc
+++ 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.