summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilliam Woodruff <william@yossarian.net>2020-01-23 02:24:16 (GMT)
committerEthan Furman <ethan@stoneleaf.us>2020-01-23 02:24:16 (GMT)
commitdd754caf144009f0569dda5053465ba2accb7b4d (patch)
tree536217d96dcb3e1d5f57b0bcd53da66059a15ad3
parent41f0ef6abbd304409c55612a08788cdd59fbc8a3 (diff)
downloadcpython-dd754caf144009f0569dda5053465ba2accb7b4d.zip
cpython-dd754caf144009f0569dda5053465ba2accb7b4d.tar.gz
cpython-dd754caf144009f0569dda5053465ba2accb7b4d.tar.bz2
bpo-29435: Allow is_tarfile to take a filelike obj (GH-18090)
`is_tarfile()` now supports `name` being a file or file-like object.
-rw-r--r--Doc/library/tarfile.rst5
-rwxr-xr-xLib/tarfile.py7
-rw-r--r--Lib/test/test_tarfile.py32
-rw-r--r--Misc/ACKS1
-rw-r--r--Misc/NEWS.d/next/Library/2020-01-20-18-48-00.bpo-29435.qqJ2Ax.rst2
5 files changed, 45 insertions, 2 deletions
diff --git a/Doc/library/tarfile.rst b/Doc/library/tarfile.rst
index c34f2c4..459e4ad 100644
--- a/Doc/library/tarfile.rst
+++ b/Doc/library/tarfile.rst
@@ -159,7 +159,10 @@ Some facts and figures:
.. function:: is_tarfile(name)
Return :const:`True` if *name* is a tar archive file, that the :mod:`tarfile`
- module can read.
+ module can read. *name* may be a :class:`str`, file, or file-like object.
+
+ .. versionchanged:: 3.9
+ Support for file and file-like objects.
The :mod:`tarfile` module defines the following exceptions:
diff --git a/Lib/tarfile.py b/Lib/tarfile.py
index 2c06f91..d0b748c 100755
--- a/Lib/tarfile.py
+++ b/Lib/tarfile.py
@@ -2461,9 +2461,14 @@ class TarFile(object):
def is_tarfile(name):
"""Return True if name points to a tar archive that we
are able to handle, else return False.
+
+ 'name' should be a string, file, or file-like object.
"""
try:
- t = open(name)
+ if hasattr(name, "read"):
+ t = open(fileobj=name)
+ else:
+ t = open(name)
t.close()
return True
except TarError:
diff --git a/Lib/test/test_tarfile.py b/Lib/test/test_tarfile.py
index 15324a4..6a90108 100644
--- a/Lib/test/test_tarfile.py
+++ b/Lib/test/test_tarfile.py
@@ -319,6 +319,38 @@ class LzmaListTest(LzmaTest, ListTest):
class CommonReadTest(ReadTest):
+ def test_is_tarfile_erroneous(self):
+ with open(tmpname, "wb"):
+ pass
+
+ # is_tarfile works on filenames
+ self.assertFalse(tarfile.is_tarfile(tmpname))
+
+ # is_tarfile works on path-like objects
+ self.assertFalse(tarfile.is_tarfile(pathlib.Path(tmpname)))
+
+ # is_tarfile works on file objects
+ with open(tmpname, "rb") as fobj:
+ self.assertFalse(tarfile.is_tarfile(fobj))
+
+ # is_tarfile works on file-like objects
+ self.assertFalse(tarfile.is_tarfile(io.BytesIO(b"invalid")))
+
+ def test_is_tarfile_valid(self):
+ # is_tarfile works on filenames
+ self.assertTrue(tarfile.is_tarfile(self.tarname))
+
+ # is_tarfile works on path-like objects
+ self.assertTrue(tarfile.is_tarfile(pathlib.Path(self.tarname)))
+
+ # is_tarfile works on file objects
+ with open(self.tarname, "rb") as fobj:
+ self.assertTrue(tarfile.is_tarfile(fobj))
+
+ # is_tarfile works on file-like objects
+ with open(self.tarname, "rb") as fobj:
+ self.assertTrue(tarfile.is_tarfile(io.BytesIO(fobj.read())))
+
def test_empty_tarfile(self):
# Test for issue6123: Allow opening empty archives.
# This test checks if tarfile.open() is able to open an empty tar
diff --git a/Misc/ACKS b/Misc/ACKS
index 3e45d5d..7e4b81b 100644
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -1856,6 +1856,7 @@ Klaus-Juergen Wolf
Dan Wolfe
Richard Wolff
Adam Woodbeck
+William Woodruff
Steven Work
Gordon Worley
Darren Worrall
diff --git a/Misc/NEWS.d/next/Library/2020-01-20-18-48-00.bpo-29435.qqJ2Ax.rst b/Misc/NEWS.d/next/Library/2020-01-20-18-48-00.bpo-29435.qqJ2Ax.rst
new file mode 100644
index 0000000..eabc942
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2020-01-20-18-48-00.bpo-29435.qqJ2Ax.rst
@@ -0,0 +1,2 @@
+Allow :func:`tarfile.is_tarfile` to be used with file and file-like
+objects, like :func:`zipfile.is_zipfile`. Patch by William Woodruff.