bpo-29110: Fix file object leak in aifc.open (GH-356)

diff --git a/Lib/aifc.py b/Lib/aifc.py
index c9a021e..e678327 100644
--- a/Lib/aifc.py
+++ b/Lib/aifc.py
@@ -288,6 +288,8 @@
     # _ssnd_chunk -- instantiation of a chunk class for the SSND chunk
     # _framesize -- size of one frame in the file
 
+    _file = None  # Set here since __del__ checks it
+
     def initfp(self, file):
         self._version = 0
         self._decomp = None
@@ -341,10 +343,16 @@
             self._decomp.SetParams(params)
 
     def __init__(self, f):
-        if type(f) == type(''):
+        if isinstance(f, basestring):
             f = __builtin__.open(f, 'rb')
-        # else, assume it is an open file object already
-        self.initfp(f)
+            try:
+                self.initfp(f)
+            except:
+                f.close()
+                raise
+        else:
+            # assume it is an open file object already
+            self.initfp(f)
 
     #
     # User visible methods.
@@ -562,8 +570,10 @@
     # _datalength -- the size of the audio samples written to the header
     # _datawritten -- the size of the audio samples actually written
 
+    _file = None  # Set here since __del__ checks it
+
     def __init__(self, f):
-        if type(f) == type(''):
+        if isinstance(f, basestring):
             filename = f
             f = __builtin__.open(f, 'wb')
         else:
diff --git a/Lib/test/test_aifc.py b/Lib/test/test_aifc.py
index d4e9de5..d1b7dd0 100644
--- a/Lib/test/test_aifc.py
+++ b/Lib/test/test_aifc.py
@@ -129,6 +129,18 @@
         #This file contains chunk types aifc doesn't recognize.
         self.f = aifc.open(findfile('Sine-1000Hz-300ms.aif'))
 
+    def test_close_opened_files_on_error(self):
+        non_aifc_file = findfile('pluck-pcm8.wav', subdir='audiodata')
+
+        class Aifc(aifc.Aifc_read):
+            def __init__(self):
+                pass
+
+        a = Aifc()
+        with self.assertRaises(aifc.Error):
+            aifc.Aifc_read.__init__(a, non_aifc_file)
+        self.assertTrue(a._file.closed)
+
     def test_write_markers_values(self):
         fout = aifc.open(io.BytesIO(), 'wb')
         self.assertEqual(fout.getmarkers(), None)