Issue #16485: Fix file descriptor not being closed if file header patching fails...
authorSerhiy Storchaka <storchaka@gmail.com>
Sat, 29 Dec 2012 20:25:59 +0000 (22:25 +0200)
committerSerhiy Storchaka <storchaka@gmail.com>
Sat, 29 Dec 2012 20:25:59 +0000 (22:25 +0200)
Lib/aifc.py
Lib/test/test_aifc.py
Misc/NEWS

index b8adc852ed60bc9e012e3cc387d11c122a8eb189..a0cfe5fc57e1ee76d440b0f4181bdd8c41b04312 100644 (file)
@@ -732,22 +732,28 @@ class Aifc_write:
             self._patchheader()
 
     def close(self):
-        self._ensure_header_written(0)
-        if self._datawritten & 1:
-            # quick pad to even size
-            self._file.write(chr(0))
-            self._datawritten = self._datawritten + 1
-        self._writemarkers()
-        if self._nframeswritten != self._nframes or \
-              self._datalength != self._datawritten or \
-              self._marklength:
-            self._patchheader()
-        if self._comp:
-            self._comp.CloseCompressor()
-            self._comp = None
-        # Prevent ref cycles
-        self._convert = None
-        self._file.close()
+        if self._file is None:
+            return
+        try:
+            self._ensure_header_written(0)
+            if self._datawritten & 1:
+                # quick pad to even size
+                self._file.write(chr(0))
+                self._datawritten = self._datawritten + 1
+            self._writemarkers()
+            if self._nframeswritten != self._nframes or \
+                  self._datalength != self._datawritten or \
+                  self._marklength:
+                self._patchheader()
+            if self._comp:
+                self._comp.CloseCompressor()
+                self._comp = None
+        finally:
+            # Prevent ref cycles
+            self._convert = None
+            f = self._file
+            self._file = None
+            f.close()
 
     #
     # Internal methods.
index e4928382582b466e3872f78acb20b6384b51ae27..62b3d1801842d9e8bf85769ad4c0a59afb5d37ea 100644 (file)
@@ -106,6 +106,13 @@ class AIFCTest(unittest.TestCase):
         self.assertEqual(testfile.closed, False)
         f.close()
         self.assertEqual(testfile.closed, True)
+        testfile = open(TESTFN, 'wb')
+        fout = aifc.open(testfile, 'wb')
+        self.assertFalse(testfile.closed)
+        with self.assertRaises(aifc.Error):
+            fout.close()
+        self.assertTrue(testfile.closed)
+        fout.close() # do nothing
 
 
 class AIFCLowLevelTest(unittest.TestCase):
index f087f415d6a3ca3d024fd3ab02e54eac8c60bdef..8ec9675fb475515444403e3a960b85d68ce43c12 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -175,6 +175,9 @@ Core and Builtins
 Library
 -------
 
+- Issue #16485: Fix file descriptor not being closed if file header patching
+  fails on closing of aifc file.
+
 - Issue #12065: connect_ex() on an SSL socket now returns the original errno
   when the socket's timeout expires (it used to return None).