When iterating over a range of a file, always close it

This is needed on Pythons without reference counting garbage collectors (e.g.
PyPy).

Change-Id: I1d06eb8fe08ee6eeb45caa47b653d6af0bb18267
This commit is contained in:
Alex Gaynor 2013-07-29 22:41:29 -07:00
parent 6a9f55d876
commit 22e7cbceed
2 changed files with 18 additions and 8 deletions

View File

@ -274,14 +274,18 @@ class DiskFile(object):
length = stop - start
else:
length = None
for chunk in self:
if length is not None:
length -= len(chunk)
if length < 0:
# Chop off the extra:
yield chunk[:length]
break
yield chunk
try:
for chunk in self:
if length is not None:
length -= len(chunk)
if length < 0:
# Chop off the extra:
yield chunk[:length]
break
yield chunk
finally:
if not self.suppress_file_closing:
self.close()
def app_iter_ranges(self, ranges, content_type, boundary, size):
"""Returns an iterator over the data file for a set of ranges"""

View File

@ -71,6 +71,12 @@ class TestDiskFile(unittest.TestCase):
FakeLogger(), keep_data_fp=True)
self.assertEqual(''.join(df.app_iter_range(5, None)), '67890')
def test_disk_file_app_iter_partial_closes(self):
df = self._create_test_file('1234567890')
it = df.app_iter_range(0, 5)
self.assertEqual(''.join(it), '12345')
self.assertEqual(df.fp, None)
def test_disk_file_app_iter_ranges(self):
df = self._create_test_file('012345678911234567892123456789')
it = df.app_iter_ranges([(0, 10), (10, 20), (20, 30)], 'plain/text',