]> granicus.if.org Git - python/commitdiff
Issue #20243: TarFile no longer raise ReadError when opened in write mode.
authorSerhiy Storchaka <storchaka@gmail.com>
Sat, 18 Jan 2014 14:14:10 +0000 (16:14 +0200)
committerSerhiy Storchaka <storchaka@gmail.com>
Sat, 18 Jan 2014 14:14:10 +0000 (16:14 +0200)
Lib/tarfile.py
Lib/test/test_tarfile.py
Misc/NEWS

index 8a69988c086b0bdf029b973873b9ae9e8cbe4ea9..6c40cb95964f7759bcf385dd9b1bd0aabf15df65 100755 (executable)
@@ -1628,19 +1628,22 @@ class TarFile(object):
         except (ImportError, AttributeError):
             raise CompressionError("gzip module is not available")
 
-        extfileobj = fileobj is not None
         try:
             fileobj = gzip.GzipFile(name, mode + "b", compresslevel, fileobj)
+        except OSError:
+            if fileobj is not None and mode == 'r':
+                raise ReadError("not a gzip file")
+            raise
+
+        try:
             t = cls.taropen(name, mode, fileobj, **kwargs)
-        except IOError:
-            if not extfileobj and fileobj is not None:
-                fileobj.close()
-            if fileobj is None:
-                raise
-            raise ReadError("not a gzip file")
+        except OSError:
+            fileobj.close()
+            if mode == 'r':
+                raise ReadError("not a gzip file")
+            raise
         except:
-            if not extfileobj and fileobj is not None:
-                fileobj.close()
+            fileobj.close()
             raise
         t._extfileobj = False
         return t
@@ -1665,7 +1668,9 @@ class TarFile(object):
             t = cls.taropen(name, mode, fileobj, **kwargs)
         except (IOError, EOFError):
             fileobj.close()
-            raise ReadError("not a bzip2 file")
+            if mode == 'r':
+                raise ReadError("not a bzip2 file")
+            raise
         t._extfileobj = False
         return t
 
@@ -1688,7 +1693,9 @@ class TarFile(object):
             t = cls.taropen(name, mode, fileobj, **kwargs)
         except (lzma.LZMAError, EOFError):
             fileobj.close()
-            raise ReadError("not an lzma file")
+            if mode == 'r':
+                raise ReadError("not an lzma file")
+            raise
         t._extfileobj = False
         return t
 
index ceaa3aa4949970d1c128cd2eb5b4fbc20a081768..f22b908797dc31fb554a7b21b7a6a6e6c507101f 100644 (file)
@@ -1155,6 +1155,22 @@ class WriteTest(WriteTestBase, unittest.TestCase):
         finally:
             os.chdir(cwd)
 
+    def test_open_nonwritable_fileobj(self):
+        for exctype in OSError, EOFError, RuntimeError:
+            class BadFile(io.BytesIO):
+                first = True
+                def write(self, data):
+                    if self.first:
+                        self.first = False
+                        raise exctype
+
+            f = BadFile()
+            with self.assertRaises(exctype):
+                tar = tarfile.open(tmpname, self.mode, fileobj=f,
+                                   format=tarfile.PAX_FORMAT,
+                                   pax_headers={'non': 'empty'})
+            self.assertFalse(f.closed)
+
 class GzipWriteTest(GzipTest, WriteTest):
     pass
 
index 839e8fe4d8590772348c2a5aa2ff19f48d33d575..533d5c5949222e1486bec0e51aec2ddf6f0af467 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -43,6 +43,8 @@ Core and Builtins
 Library
 -------
 
+- Issue #20243: TarFile no longer raise ReadError when opened in write mode.
+
 - Issue #20238: TarFile opened with external fileobj and "w:gz" mode didn't
   write complete output on close.