have _FileIter return self from __iter__ so .close has a chance to be called
| | |
| | | if 'wsgi.file_wrapper' in environ: |
| | | app_iter = environ['wsgi.file_wrapper'](f, _BLOCK_SIZE) |
| | | else: |
| | | app_iter = _FileIter(open(path, 'rb')) |
| | | app_iter = _FileIter(open(path, 'rb'), _BLOCK_SIZE) |
| | | self.app_iter = app_iter |
| | | # assignment of content_length must come after assignment of app_iter |
| | | self.content_length = content_length |
| | |
| | | self.cache_expires = cache_max_age |
| | | |
| | | class _FileIter(object): |
| | | block_size = _BLOCK_SIZE |
| | | |
| | | def __init__(self, file): |
| | | def __init__(self, file, block_size): |
| | | self.file = file |
| | | self.block_size = block_size |
| | | |
| | | def __iter__(self): |
| | | return iter(lambda: self.file.read(self.block_size), b'') |
| | | return self |
| | | |
| | | def next(self): |
| | | val = self.file.read(self.block_size) |
| | | if not val: |
| | | raise StopIteration |
| | | return val |
| | | |
| | | __next__ = next # py3 |
| | | |
| | | def close(self): |
| | | self.file.close() |
| | |
| | | import datetime |
| | | import unittest |
| | | import io |
| | | |
| | | # 5 years from now (more or less) |
| | | fiveyrsfuture = datetime.datetime.utcnow() + datetime.timedelta(5*365) |
| | |
| | | result = self._callFUT(module) |
| | | self.assertEqual(result, False) |
| | | |
| | | class Test_FileIter(unittest.TestCase): |
| | | def _makeOne(self, file, block_size): |
| | | from pyramid.static import _FileIter |
| | | return _FileIter(file, block_size) |
| | | |
| | | def test___iter__(self): |
| | | f = io.BytesIO(b'abc') |
| | | inst = self._makeOne(f, 1) |
| | | self.assertEqual(inst.__iter__(), inst) |
| | | |
| | | def test_iteration(self): |
| | | data = b'abcdef' |
| | | f = io.BytesIO(b'abcdef') |
| | | inst = self._makeOne(f, 1) |
| | | r = b'' |
| | | for x in inst: |
| | | self.assertEqual(len(x), 1) |
| | | r+=x |
| | | self.assertEqual(r, data) |
| | | |
| | | def test_close(self): |
| | | f = io.BytesIO(b'abc') |
| | | inst = self._makeOne(f, 1) |
| | | inst.close() |
| | | self.assertTrue(f.closed) |
| | | |
| | | class DummyContext: |
| | | pass |
| | | |