[Python-checkins] cpython (2.7): Issue #20245: The open functions in the tarfile module now correctly handle

serhiy.storchaka python-checkins at python.org
Sat Jan 18 14:43:41 CET 2014


http://hg.python.org/cpython/rev/8edb892f4d69
changeset:   88542:8edb892f4d69
branch:      2.7
parent:      88519:23a760bdd4b1
user:        Serhiy Storchaka <storchaka at gmail.com>
date:        Sat Jan 18 15:35:19 2014 +0200
summary:
  Issue #20245: The open functions in the tarfile module now correctly handle empty mode.

files:
  Lib/tarfile.py           |  15 ++++++++-------
  Lib/test/test_tarfile.py |  14 ++++++++++++++
  Misc/NEWS                |   3 +++
  3 files changed, 25 insertions(+), 7 deletions(-)


diff --git a/Lib/tarfile.py b/Lib/tarfile.py
--- a/Lib/tarfile.py
+++ b/Lib/tarfile.py
@@ -1508,10 +1508,11 @@
            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):
@@ -1681,7 +1682,7 @@
             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'")
 
             t = cls(name, filemode,
@@ -1690,7 +1691,7 @@
             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")
@@ -1699,7 +1700,7 @@
     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)
 
@@ -1708,7 +1709,7 @@
         """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:
@@ -1734,7 +1735,7 @@
         """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:
diff --git a/Lib/test/test_tarfile.py b/Lib/test/test_tarfile.py
--- a/Lib/test/test_tarfile.py
+++ b/Lib/test/test_tarfile.py
@@ -213,6 +213,7 @@
 
 
 class MiscReadTest(CommonReadTest):
+    taropen = tarfile.TarFile.taropen
 
     def test_no_name_argument(self):
         fobj = open(self.tarname, "rb")
@@ -233,6 +234,17 @@
         tar = tarfile.open(fileobj=fobj, mode=self.mode)
         self.assertEqual(tar.name, None)
 
+    def test_illegal_mode_arg(self):
+        with open(tmpname, 'wb'):
+            pass
+        self.addCleanup(os.unlink, tmpname)
+        with self.assertRaisesRegexp(ValueError, 'mode must be '):
+            tar = self.taropen(tmpname, 'q')
+        with self.assertRaisesRegexp(ValueError, 'mode must be '):
+            tar = self.taropen(tmpname, 'rw')
+        with self.assertRaisesRegexp(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.
@@ -1543,6 +1555,7 @@
 class GzipMiscReadTest(MiscReadTest):
     tarname = gzipname
     mode = "r:gz"
+    taropen = tarfile.TarFile.gzopen
 class GzipUstarReadTest(UstarReadTest):
     tarname = gzipname
     mode = "r:gz"
@@ -1558,6 +1571,7 @@
 class Bz2MiscReadTest(MiscReadTest):
     tarname = bz2name
     mode = "r:bz2"
+    taropen = tarfile.TarFile.bz2open
 class Bz2UstarReadTest(UstarReadTest):
     tarname = bz2name
     mode = "r:bz2"
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -35,6 +35,9 @@
 Library
 -------
 
+- Issue #20245: The open functions in the tarfile module now correctly handle
+  empty mode.
+
 - Issue #20086: Restored the use of locale-independent mapping instead of
   locale-dependent str.lower() in locale.normalize().
 

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list