Commit 53ad0cd2 authored by Serhiy Storchaka's avatar Serhiy Storchaka

Issue #20245: The open functions in the tarfile module now correctly handle empty mode.

parent af69fe23
......@@ -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:
......
......@@ -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.
......
......@@ -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.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment