From e7829bdf122f1b481a09c4aab00821f02052191b Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Wed, 16 Jul 2014 23:58:12 +0300 Subject: Issue 21044: tarfile.open() now handles fileobj with an integer 'name' attribute. Based on patch by Martin Panter. --- Lib/tarfile.py | 3 ++- Lib/test/test_tarfile.py | 38 +++++++++++++++++++++++++++++++++----- Misc/ACKS | 1 + Misc/NEWS | 3 +++ 4 files changed, 39 insertions(+), 6 deletions(-) diff --git a/Lib/tarfile.py b/Lib/tarfile.py index 57ea877..db5ff7f 100644 --- a/Lib/tarfile.py +++ b/Lib/tarfile.py @@ -1522,7 +1522,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, basestring)): name = fileobj.name if hasattr(fileobj, "mode"): self._mode = fileobj.mode diff --git a/Lib/test/test_tarfile.py b/Lib/test/test_tarfile.py index ff3265f..7d13398 100644 --- a/Lib/test/test_tarfile.py +++ b/Lib/test/test_tarfile.py @@ -1,6 +1,7 @@ # -*- coding: iso-8859-15 -*- import sys +import io import os import shutil import StringIO @@ -289,24 +290,49 @@ class CommonReadTest(ReadTest): class MiscReadTest(CommonReadTest): taropen = tarfile.TarFile.taropen + def requires_name_attribute(self): + pass + def test_no_name_argument(self): - fobj = open(self.tarname, "rb") - tar = tarfile.open(fileobj=fobj, mode=self.mode) - self.assertEqual(tar.name, os.path.abspath(fobj.name)) + self.requires_name_attribute() + with open(self.tarname, "rb") as fobj: + 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): data = open(self.tarname, "rb").read() fobj = StringIO.StringIO(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): data = open(self.tarname, "rb").read() fobj = StringIO.StringIO(data) fobj.name = "" tar = tarfile.open(fileobj=fobj, mode=self.mode) - 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 io.open(fd, 'rb') as fobj: + self.assertIsInstance(fobj.name, int) + with tarfile.open(fileobj=fobj, mode=self.mode) as tar: + self.assertIsNone(tar.name) + + @test_support.requires_unicode + def test_unicode_name_attribute(self): + self.requires_name_attribute() + tarname = unicode(self.tarname, test_support.TESTFN_ENCODING) + with io.open(tarname, 'rb') as fobj: + self.assertIsInstance(fobj.name, unicode) + with tarfile.open(fileobj=fobj, mode=self.mode) as tar: + self.assertIsInstance(tar.name, unicode) + self.assertEqual(tar.name, os.path.abspath(fobj.name)) def test_illegal_mode_arg(self): with open(tmpname, 'wb'): @@ -1668,6 +1694,8 @@ class Bz2MiscReadTest(MiscReadTest): tarname = bz2name mode = "r:bz2" taropen = tarfile.TarFile.bz2open + def requires_name_attribute(self): + self.skipTest("BZ2File have no name attribute") class Bz2UstarReadTest(UstarReadTest): tarname = bz2name mode = "r:bz2" diff --git a/Misc/ACKS b/Misc/ACKS index 59f75cf..27be949 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -995,6 +995,7 @@ Mike Pall Todd R. Palmer Juan David Ibáñez Palomar Jan Palus +Martin Panter Mathias Panzenböck M. Papillon Peter Parente diff --git a/Misc/NEWS b/Misc/NEWS index 0b78b5f..d2fc3e2 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -13,6 +13,9 @@ Core and Builtins Library ------- +- Issue 21044: tarfile.open() now handles fileobj with an integer 'name' + attribute. Based on patch by Martin Panter. + - Issue #21151: Fixed a segfault in the _winreg module when ``None`` is passed as a ``REG_BINARY`` value to SetValueEx. Patch by John Ehresman. -- cgit v0.12