Skip to content

Commit

Permalink
Merged revisions 67946 via svnmerge from
Browse files Browse the repository at this point in the history
svn+ssh://[email protected]/python/trunk

........
  r67946 | antoine.pitrou | 2008-12-27 16:43:12 +0100 (sam., 27 déc. 2008) | 4 lines

  Issue python#4756: zipfile.is_zipfile() now supports file-like objects.
  Patch by Gabriel Genellina.
........
  • Loading branch information
pitrou committed Dec 27, 2008
1 parent d88e8fa commit db5fe66
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 14 deletions.
6 changes: 4 additions & 2 deletions Doc/library/zipfile.rst
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,11 @@ The module defines the following items:
.. function:: is_zipfile(filename)

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
which have appended comments.
otherwise returns ``False``. *filename* may be a file or file-like object too.
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

Expand Down
39 changes: 34 additions & 5 deletions Lib/test/test_zipfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -621,20 +621,49 @@ def testCloseErroneousFile(self):
def testIsZipErroneousFile(self):
# This test checks that the is_zipfile function correctly identifies
# a file that is not a zip file
fp = open(TESTFN, "w")
fp.write("this is not a legal zip file\n")
fp.close()

# - passing a filename
with open(TESTFN, "w") as fp:
fp.write("this is not a legal zip file\n")
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):
# This test checks that the is_zipfile function correctly identifies
# a file that is a zip file

# - passing a filename
zipf = zipfile.ZipFile(TESTFN, mode="w")
zipf.writestr("foo.txt", b"O, for a Muse of Fire!")
zipf.close()
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):
# make sure we don't raise an AttributeError when a partially-constructed
Expand Down
26 changes: 19 additions & 7 deletions Lib/zipfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,18 +130,30 @@ class LargeZipFile(Exception):
_CD64_DIRECTORY_SIZE = 8
_CD64_OFFSET_START_CENTDIR = 9

def is_zipfile(filename):
"""Quickly see if file is a ZIP file by checking the magic number."""
def _check_zipfile(fp):
try:
fpin = io.open(filename, "rb")
endrec = _EndRecData(fpin)
fpin.close()
if endrec:
return True # file has correct magic number
if _EndRecData(fp):
return True # file has correct magic number
except IOError:
pass
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):
"""
Read the ZIP64 end-of-archive records and use that to update endrec
Expand Down
3 changes: 3 additions & 0 deletions Misc/NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ Core and Builtins
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
boundary.

Expand Down

0 comments on commit db5fe66

Please sign in to comment.