Merged revisions 67946 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk ........ r67946 | antoine.pitrou | 2008-12-27 16:43:12 +0100 (sam., 27 déc. 2008) | 4 lines Issue #4756: zipfile.is_zipfile() now supports file-like objects. Patch by Gabriel Genellina. ........
This commit is contained in:
parent
d88e8fab14
commit
db5fe66731
|
@ -64,9 +64,11 @@ The module defines the following items:
|
||||||
.. function:: is_zipfile(filename)
|
.. function:: is_zipfile(filename)
|
||||||
|
|
||||||
Returns ``True`` if *filename* is a valid ZIP file based on its magic number,
|
Returns ``True`` if *filename* is a valid ZIP file based on its magic number,
|
||||||
otherwise returns ``False``. This module does not currently handle ZIP files
|
otherwise returns ``False``. *filename* may be a file or file-like object too.
|
||||||
which have appended comments.
|
This module does not currently handle ZIP files which have appended comments.
|
||||||
|
|
||||||
|
.. versionchanged:: 2.7
|
||||||
|
Support for file and file-like objects.
|
||||||
|
|
||||||
.. data:: ZIP_STORED
|
.. data:: ZIP_STORED
|
||||||
|
|
||||||
|
|
|
@ -621,20 +621,49 @@ class OtherTests(unittest.TestCase):
|
||||||
def testIsZipErroneousFile(self):
|
def testIsZipErroneousFile(self):
|
||||||
# This test checks that the is_zipfile function correctly identifies
|
# This test checks that the is_zipfile function correctly identifies
|
||||||
# a file that is not a zip file
|
# a file that is not a zip file
|
||||||
fp = open(TESTFN, "w")
|
|
||||||
fp.write("this is not a legal zip file\n")
|
# - passing a filename
|
||||||
fp.close()
|
with open(TESTFN, "w") as fp:
|
||||||
|
fp.write("this is not a legal zip file\n")
|
||||||
chk = zipfile.is_zipfile(TESTFN)
|
chk = zipfile.is_zipfile(TESTFN)
|
||||||
self.assert_(chk is False)
|
self.assert_(not chk)
|
||||||
|
# - passing a file object
|
||||||
|
with open(TESTFN, "rb") as fp:
|
||||||
|
chk = zipfile.is_zipfile(fp)
|
||||||
|
self.assert_(not chk)
|
||||||
|
# - passing a file-like object
|
||||||
|
fp = io.BytesIO()
|
||||||
|
fp.write(b"this is not a legal zip file\n")
|
||||||
|
chk = zipfile.is_zipfile(fp)
|
||||||
|
self.assert_(not chk)
|
||||||
|
fp.seek(0,0)
|
||||||
|
chk = zipfile.is_zipfile(fp)
|
||||||
|
self.assert_(not chk)
|
||||||
|
|
||||||
def testIsZipValidFile(self):
|
def testIsZipValidFile(self):
|
||||||
# This test checks that the is_zipfile function correctly identifies
|
# This test checks that the is_zipfile function correctly identifies
|
||||||
# a file that is a zip file
|
# a file that is a zip file
|
||||||
|
|
||||||
|
# - passing a filename
|
||||||
zipf = zipfile.ZipFile(TESTFN, mode="w")
|
zipf = zipfile.ZipFile(TESTFN, mode="w")
|
||||||
zipf.writestr("foo.txt", b"O, for a Muse of Fire!")
|
zipf.writestr("foo.txt", b"O, for a Muse of Fire!")
|
||||||
zipf.close()
|
zipf.close()
|
||||||
chk = zipfile.is_zipfile(TESTFN)
|
chk = zipfile.is_zipfile(TESTFN)
|
||||||
self.assert_(chk is True)
|
self.assert_(chk)
|
||||||
|
# - passing a file object
|
||||||
|
with open(TESTFN, "rb") as fp:
|
||||||
|
chk = zipfile.is_zipfile(fp)
|
||||||
|
self.assert_(chk)
|
||||||
|
fp.seek(0,0)
|
||||||
|
zip_contents = fp.read()
|
||||||
|
# - passing a file-like object
|
||||||
|
fp = io.BytesIO()
|
||||||
|
fp.write(zip_contents)
|
||||||
|
chk = zipfile.is_zipfile(fp)
|
||||||
|
self.assert_(chk)
|
||||||
|
fp.seek(0,0)
|
||||||
|
chk = zipfile.is_zipfile(fp)
|
||||||
|
self.assert_(chk)
|
||||||
|
|
||||||
def testNonExistentFileRaisesIOError(self):
|
def testNonExistentFileRaisesIOError(self):
|
||||||
# make sure we don't raise an AttributeError when a partially-constructed
|
# make sure we don't raise an AttributeError when a partially-constructed
|
||||||
|
|
|
@ -130,18 +130,30 @@ _CD64_NUMBER_ENTRIES_TOTAL = 7
|
||||||
_CD64_DIRECTORY_SIZE = 8
|
_CD64_DIRECTORY_SIZE = 8
|
||||||
_CD64_OFFSET_START_CENTDIR = 9
|
_CD64_OFFSET_START_CENTDIR = 9
|
||||||
|
|
||||||
def is_zipfile(filename):
|
def _check_zipfile(fp):
|
||||||
"""Quickly see if file is a ZIP file by checking the magic number."""
|
|
||||||
try:
|
try:
|
||||||
fpin = io.open(filename, "rb")
|
if _EndRecData(fp):
|
||||||
endrec = _EndRecData(fpin)
|
return True # file has correct magic number
|
||||||
fpin.close()
|
|
||||||
if endrec:
|
|
||||||
return True # file has correct magic number
|
|
||||||
except IOError:
|
except IOError:
|
||||||
pass
|
pass
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def is_zipfile(filename):
|
||||||
|
"""Quickly see if a file is a ZIP file by checking the magic number.
|
||||||
|
|
||||||
|
The filename argument may be a file or file-like object too.
|
||||||
|
"""
|
||||||
|
result = False
|
||||||
|
try:
|
||||||
|
if hasattr(filename, "read"):
|
||||||
|
result = _check_zipfile(fp=filename)
|
||||||
|
else:
|
||||||
|
with open(filename, "rb") as fp:
|
||||||
|
result = _check_zipfile(fp)
|
||||||
|
except IOError:
|
||||||
|
pass
|
||||||
|
return result
|
||||||
|
|
||||||
def _EndRecData64(fpin, offset, endrec):
|
def _EndRecData64(fpin, offset, endrec):
|
||||||
"""
|
"""
|
||||||
Read the ZIP64 end-of-archive records and use that to update endrec
|
Read the ZIP64 end-of-archive records and use that to update endrec
|
||||||
|
|
|
@ -59,6 +59,9 @@ Core and Builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #4756: zipfile.is_zipfile() now supports file-like objects. Patch by
|
||||||
|
Gabriel Genellina.
|
||||||
|
|
||||||
- Issue #4574: reading an UTF16-encoded text file crashes if \r on 64-char
|
- Issue #4574: reading an UTF16-encoded text file crashes if \r on 64-char
|
||||||
boundary.
|
boundary.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue