[pypy-commit] pypy default: merge heads
arigo
noreply at buildbot.pypy.org
Thu Jan 31 22:29:11 CET 2013
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r60795:620c44fd4b9f
Date: 2013-01-31 22:28 +0100
http://bitbucket.org/pypy/pypy/changeset/620c44fd4b9f/
Log: merge heads
diff --git a/lib-python/2.7/test/test_zipfile.py b/lib-python/2.7/test/test_zipfile.py
--- a/lib-python/2.7/test/test_zipfile.py
+++ b/lib-python/2.7/test/test_zipfile.py
@@ -1213,6 +1213,17 @@
self.assertEqual(data1, '1'*FIXEDTEST_SIZE)
self.assertEqual(data2, '2'*FIXEDTEST_SIZE)
+ def test_many_opens(self):
+ # Verify that read() and open() promptly close the file descriptor,
+ # and don't rely on the garbage collector to free resources.
+ with zipfile.ZipFile(TESTFN2, mode="r") as zipf:
+ for x in range(100):
+ zipf.read('ones')
+ with zipf.open('ones') as zopen1:
+ pass
+ for x in range(10):
+ self.assertLess(open('/dev/null').fileno(), 100)
+
def tearDown(self):
unlink(TESTFN2)
diff --git a/lib-python/2.7/zipfile.py b/lib-python/2.7/zipfile.py
--- a/lib-python/2.7/zipfile.py
+++ b/lib-python/2.7/zipfile.py
@@ -475,9 +475,11 @@
# Search for universal newlines or line chunks.
PATTERN = re.compile(r'^(?P<chunk>[^\r\n]+)|(?P<newline>\n|\r\n?)')
- def __init__(self, fileobj, mode, zipinfo, decrypter=None):
+ def __init__(self, fileobj, mode, zipinfo, decrypter=None,
+ close_fileobj=False):
self._fileobj = fileobj
self._decrypter = decrypter
+ self._close_fileobj = close_fileobj
self._compress_type = zipinfo.compress_type
self._compress_size = zipinfo.compress_size
@@ -649,6 +651,12 @@
self._offset += len(data)
return data
+ def close(self):
+ try:
+ if self._close_fileobj:
+ self._fileobj.close()
+ finally:
+ super(ZipExtFile, self).close()
class ZipFile:
@@ -866,7 +874,8 @@
def read(self, name, pwd=None):
"""Return file bytes (as a string) for name."""
- return self.open(name, "r", pwd).read()
+ with self.open(name, "r", pwd) as fp:
+ return fp.read()
def open(self, name, mode="r", pwd=None):
"""Return file-like object for 'name'."""
@@ -889,8 +898,12 @@
zinfo = name
else:
# Get info object for name
- zinfo = self.getinfo(name)
-
+ try:
+ zinfo = self.getinfo(name)
+ except KeyError:
+ if not self._filePassed:
+ zef_file.close()
+ raise
zef_file.seek(zinfo.header_offset, 0)
# Skip the file header:
@@ -904,6 +917,8 @@
zef_file.read(fheader[_FH_EXTRA_FIELD_LENGTH])
if fname != zinfo.orig_filename:
+ if not self._filePassed:
+ zef_file.close()
raise BadZipfile, \
'File name in directory "%s" and header "%s" differ.' % (
zinfo.orig_filename, fname)
@@ -915,6 +930,8 @@
if not pwd:
pwd = self.pwd
if not pwd:
+ if not self._filePassed:
+ zef_file.close()
raise RuntimeError, "File %s is encrypted, " \
"password required for extraction" % name
@@ -933,9 +950,12 @@
# compare against the CRC otherwise
check_byte = (zinfo.CRC >> 24) & 0xff
if ord(h[11]) != check_byte:
+ if not self._filePassed:
+ zef_file.close()
raise RuntimeError("Bad password for file", name)
- return ZipExtFile(zef_file, mode, zinfo, zd)
+ return ZipExtFile(zef_file, mode, zinfo, zd,
+ close_fileobj=not self._filePassed)
def extract(self, member, path=None, pwd=None):
"""Extract a member from the archive to the current working directory,
@@ -993,7 +1013,7 @@
return targetpath
source = self.open(member, pwd=pwd)
- target = file(targetpath, "wb")
+ target = open(targetpath, "wb")
shutil.copyfileobj(source, target)
source.close()
target.close()
More information about the pypy-commit
mailing list