bpo-29435: Allow is_tarfile to take a filelike obj (GH-18090)
`is_tarfile()` now supports `name` being a file or file-like object.
This commit is contained in:
parent
41f0ef6abb
commit
dd754caf14
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1856,6 +1856,7 @@ Klaus-Juergen Wolf
|
|||
Dan Wolfe
|
||||
Richard Wolff
|
||||
Adam Woodbeck
|
||||
William Woodruff
|
||||
Steven Work
|
||||
Gordon Worley
|
||||
Darren Worrall
|
||||
|
|
|
@ -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.
|
Loading…
Reference in New Issue