Commit 2c6a3aed authored by Serhiy Storchaka's avatar Serhiy Storchaka

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

attribute.  Based on patch by Martin Panter.
parent 8faecbfb
...@@ -1423,7 +1423,8 @@ class TarFile(object): ...@@ -1423,7 +1423,8 @@ class TarFile(object):
fileobj = bltn_open(name, self._mode) fileobj = bltn_open(name, self._mode)
self._extfileobj = False self._extfileobj = False
else: 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 name = fileobj.name
if hasattr(fileobj, "mode"): if hasattr(fileobj, "mode"):
self._mode = fileobj.mode self._mode = fileobj.mode
......
...@@ -352,10 +352,16 @@ class CommonReadTest(ReadTest): ...@@ -352,10 +352,16 @@ class CommonReadTest(ReadTest):
class MiscReadTestBase(CommonReadTest): class MiscReadTestBase(CommonReadTest):
def requires_name_attribute(self):
pass
def test_no_name_argument(self): def test_no_name_argument(self):
self.requires_name_attribute()
with open(self.tarname, "rb") as fobj: with open(self.tarname, "rb") as fobj:
tar = tarfile.open(fileobj=fobj, mode=self.mode) self.assertIsInstance(fobj.name, str)
self.assertEqual(tar.name, os.path.abspath(fobj.name)) 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): def test_no_name_attribute(self):
with open(self.tarname, "rb") as fobj: with open(self.tarname, "rb") as fobj:
...@@ -363,7 +369,7 @@ class MiscReadTestBase(CommonReadTest): ...@@ -363,7 +369,7 @@ class MiscReadTestBase(CommonReadTest):
fobj = io.BytesIO(data) fobj = io.BytesIO(data)
self.assertRaises(AttributeError, getattr, fobj, "name") self.assertRaises(AttributeError, getattr, fobj, "name")
tar = tarfile.open(fileobj=fobj, mode=self.mode) tar = tarfile.open(fileobj=fobj, mode=self.mode)
self.assertEqual(tar.name, None) self.assertIsNone(tar.name)
def test_empty_name_attribute(self): def test_empty_name_attribute(self):
with open(self.tarname, "rb") as fobj: with open(self.tarname, "rb") as fobj:
...@@ -371,7 +377,25 @@ class MiscReadTestBase(CommonReadTest): ...@@ -371,7 +377,25 @@ class MiscReadTestBase(CommonReadTest):
fobj = io.BytesIO(data) fobj = io.BytesIO(data)
fobj.name = "" fobj.name = ""
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.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): def test_illegal_mode_arg(self):
with open(tmpname, 'wb'): with open(tmpname, 'wb'):
...@@ -549,11 +573,11 @@ class GzipMiscReadTest(GzipTest, MiscReadTestBase, unittest.TestCase): ...@@ -549,11 +573,11 @@ class GzipMiscReadTest(GzipTest, MiscReadTestBase, unittest.TestCase):
pass pass
class Bz2MiscReadTest(Bz2Test, MiscReadTestBase, unittest.TestCase): class Bz2MiscReadTest(Bz2Test, MiscReadTestBase, unittest.TestCase):
def test_no_name_argument(self): def requires_name_attribute(self):
self.skipTest("BZ2File have no name attribute") self.skipTest("BZ2File have no name attribute")
class LzmaMiscReadTest(LzmaTest, MiscReadTestBase, unittest.TestCase): class LzmaMiscReadTest(LzmaTest, MiscReadTestBase, unittest.TestCase):
def test_no_name_argument(self): def requires_name_attribute(self):
self.skipTest("LZMAFile have no name attribute") self.skipTest("LZMAFile have no name attribute")
......
...@@ -996,6 +996,7 @@ Mike Pall ...@@ -996,6 +996,7 @@ Mike Pall
Todd R. Palmer Todd R. Palmer
Juan David Ibáñez Palomar Juan David Ibáñez Palomar
Jan Palus Jan Palus
Martin Panter
Mathias Panzenböck Mathias Panzenböck
M. Papillon M. Papillon
Peter Parente Peter Parente
......
...@@ -27,6 +27,9 @@ Core and Builtins ...@@ -27,6 +27,9 @@ Core and Builtins
Library 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 #19076: Don't pass the redundant 'file' argument to self.error().
- Issue #21942: Fixed source file viewing in pydoc's server mode on Windows. - Issue #21942: Fixed source file viewing in pydoc's server mode on Windows.
......
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