]> granicus.if.org Git - python/commitdiff
Issue #20245: The open functions in the tarfile module now correctly handle empty...
authorSerhiy Storchaka <storchaka@gmail.com>
Sat, 18 Jan 2014 13:35:37 +0000 (15:35 +0200)
committerSerhiy Storchaka <storchaka@gmail.com>
Sat, 18 Jan 2014 13:35:37 +0000 (15:35 +0200)
Lib/tarfile.py
Lib/test/test_tarfile.py
Misc/NEWS

index 16d338c7384485a24b012df4e77b3ddfd51b5ebb..987c0113626ef5df845c60d7dcde9cc705df68e4 100755 (executable)
@@ -1429,10 +1429,11 @@ class TarFile(object):
            can be determined, `mode' is overridden by `fileobj's mode.
            `fileobj' is not closed, when TarFile is closed.
         """
-        if len(mode) > 1 or mode not in "raw":
+        modes = {"r": "rb", "a": "r+b", "w": "wb"}
+        if mode not in modes:
             raise ValueError("mode must be 'r', 'a' or 'w'")
         self.mode = mode
-        self._mode = {"r": "rb", "a": "r+b", "w": "wb"}[mode]
+        self._mode = modes[mode]
 
         if not fileobj:
             if self.mode == "a" and not os.path.exists(name):
@@ -1588,7 +1589,7 @@ class TarFile(object):
             filemode = filemode or "r"
             comptype = comptype or "tar"
 
-            if filemode not in "rw":
+            if filemode not in ("r", "w"):
                 raise ValueError("mode must be 'r' or 'w'")
 
             stream = _Stream(name, filemode, comptype, fileobj, bufsize)
@@ -1600,7 +1601,7 @@ class TarFile(object):
             t._extfileobj = False
             return t
 
-        elif mode in "aw":
+        elif mode in ("a", "w"):
             return cls.taropen(name, mode, fileobj, **kwargs)
 
         raise ValueError("undiscernible mode")
@@ -1609,7 +1610,7 @@ class TarFile(object):
     def taropen(cls, name, mode="r", fileobj=None, **kwargs):
         """Open uncompressed tar archive name for reading or writing.
         """
-        if len(mode) > 1 or mode not in "raw":
+        if mode not in ("r", "a", "w"):
             raise ValueError("mode must be 'r', 'a' or 'w'")
         return cls(name, mode, fileobj, **kwargs)
 
@@ -1618,7 +1619,7 @@ class TarFile(object):
         """Open gzip compressed tar archive name for reading or writing.
            Appending is not allowed.
         """
-        if len(mode) > 1 or mode not in "rw":
+        if mode not in ("r", "w"):
             raise ValueError("mode must be 'r' or 'w'")
 
         try:
@@ -1649,7 +1650,7 @@ class TarFile(object):
         """Open bzip2 compressed tar archive name for reading or writing.
            Appending is not allowed.
         """
-        if len(mode) > 1 or mode not in "rw":
+        if mode not in ("r", "w"):
             raise ValueError("mode must be 'r' or 'w'.")
 
         try:
index 18dd39073025fab7157066db9742872b71783128..6986fc00bd68d9d942346538f39fcf7c458935ed 100644 (file)
@@ -41,6 +41,7 @@ class TarTest:
     tarname = tarname
     suffix = ''
     open = io.FileIO
+    taropen = tarfile.TarFile.taropen
 
     @property
     def mode(self):
@@ -51,18 +52,21 @@ class GzipTest:
     tarname = gzipname
     suffix = 'gz'
     open = gzip.GzipFile if gzip else None
+    taropen = tarfile.TarFile.gzopen
 
 @support.requires_bz2
 class Bz2Test:
     tarname = bz2name
     suffix = 'bz2'
     open = bz2.BZ2File if bz2 else None
+    taropen = tarfile.TarFile.bz2open
 
 @support.requires_lzma
 class LzmaTest:
     tarname = xzname
     suffix = 'xz'
     open = lzma.LZMAFile if lzma else None
+    taropen = tarfile.TarFile.xzopen
 
 
 class ReadTest(TarTest):
@@ -287,6 +291,16 @@ class MiscReadTestBase(CommonReadTest):
         with tarfile.open(fileobj=fobj, mode=self.mode) as tar:
             self.assertEqual(tar.name, None)
 
+    def test_illegal_mode_arg(self):
+        with open(tmpname, 'wb'):
+            pass
+        with self.assertRaisesRegex(ValueError, 'mode must be '):
+            tar = self.taropen(tmpname, 'q')
+        with self.assertRaisesRegex(ValueError, 'mode must be '):
+            tar = self.taropen(tmpname, 'rw')
+        with self.assertRaisesRegex(ValueError, 'mode must be '):
+            tar = self.taropen(tmpname, '')
+
     def test_fileobj_with_offset(self):
         # Skip the first member and store values from the second member
         # of the testtar.
index f64a29835ba0c7544f42ffb163833ce1024904e8..4e9be22576c68d0269ecdf02f1bf853c321f617e 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -43,6 +43,9 @@ Core and Builtins
 Library
 -------
 
+- Issue #20245: The open functions in the tarfile module now correctly handle
+  empty mode.
+
 - Issue #20242: Fixed basicConfig() format strings for the alternative
   formatting styles. Thanks to kespindler for the bug report and patch.