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