Issue 21044: tarfile.open() now handles fileobj with an integer 'name'

attribute.  Based on patch by Martin Panter.
This commit is contained in:
Serhiy Storchaka 2014-07-16 23:58:58 +03:00
parent 8faecbfb42
commit 2c6a3aedeb
4 changed files with 36 additions and 7 deletions

View File

@ -1423,7 +1423,8 @@ class TarFile(object):
fileobj = bltn_open(name, self._mode)
self._extfileobj = False
else:
if name is None and hasattr(fileobj, "name"):
if (name is None and hasattr(fileobj, "name") and
isinstance(fileobj.name, (str, bytes))):
name = fileobj.name
if hasattr(fileobj, "mode"):
self._mode = fileobj.mode

View File

@ -352,10 +352,16 @@ class CommonReadTest(ReadTest):
class MiscReadTestBase(CommonReadTest):
def requires_name_attribute(self):
pass
def test_no_name_argument(self):
self.requires_name_attribute()
with open(self.tarname, "rb") as fobj:
tar = tarfile.open(fileobj=fobj, mode=self.mode)
self.assertEqual(tar.name, os.path.abspath(fobj.name))
self.assertIsInstance(fobj.name, str)
with tarfile.open(fileobj=fobj, mode=self.mode) as tar:
self.assertIsInstance(tar.name, str)
self.assertEqual(tar.name, os.path.abspath(fobj.name))
def test_no_name_attribute(self):
with open(self.tarname, "rb") as fobj:
@ -363,7 +369,7 @@ class MiscReadTestBase(CommonReadTest):
fobj = io.BytesIO(data)
self.assertRaises(AttributeError, getattr, fobj, "name")
tar = tarfile.open(fileobj=fobj, mode=self.mode)
self.assertEqual(tar.name, None)
self.assertIsNone(tar.name)
def test_empty_name_attribute(self):
with open(self.tarname, "rb") as fobj:
@ -371,7 +377,25 @@ class MiscReadTestBase(CommonReadTest):
fobj = io.BytesIO(data)
fobj.name = ""
with tarfile.open(fileobj=fobj, mode=self.mode) as tar:
self.assertEqual(tar.name, None)
self.assertIsNone(tar.name)
def test_int_name_attribute(self):
# Issue 21044: tarfile.open() should handle fileobj with an integer
# 'name' attribute.
fd = os.open(self.tarname, os.O_RDONLY)
with open(fd, 'rb') as fobj:
self.assertIsInstance(fobj.name, int)
with tarfile.open(fileobj=fobj, mode=self.mode) as tar:
self.assertIsNone(tar.name)
def test_bytes_name_attribute(self):
self.requires_name_attribute()
tarname = os.fsencode(self.tarname)
with open(tarname, 'rb') as fobj:
self.assertIsInstance(fobj.name, bytes)
with tarfile.open(fileobj=fobj, mode=self.mode) as tar:
self.assertIsInstance(tar.name, bytes)
self.assertEqual(tar.name, os.path.abspath(fobj.name))
def test_illegal_mode_arg(self):
with open(tmpname, 'wb'):
@ -549,11 +573,11 @@ class GzipMiscReadTest(GzipTest, MiscReadTestBase, unittest.TestCase):
pass
class Bz2MiscReadTest(Bz2Test, MiscReadTestBase, unittest.TestCase):
def test_no_name_argument(self):
def requires_name_attribute(self):
self.skipTest("BZ2File have no name attribute")
class LzmaMiscReadTest(LzmaTest, MiscReadTestBase, unittest.TestCase):
def test_no_name_argument(self):
def requires_name_attribute(self):
self.skipTest("LZMAFile have no name attribute")

View File

@ -996,6 +996,7 @@ Mike Pall
Todd R. Palmer
Juan David Ibáñez Palomar
Jan Palus
Martin Panter
Mathias Panzenböck
M. Papillon
Peter Parente

View File

@ -27,6 +27,9 @@ Core and Builtins
Library
-------
- Issue 21044: tarfile.open() now handles fileobj with an integer 'name'
attribute. Based on patch by Martin Panter.
- Issue #19076: Don't pass the redundant 'file' argument to self.error().
- Issue #21942: Fixed source file viewing in pydoc's server mode on Windows.