Fixed Executor.map not submitting futures until iter.next() is called

This commit is contained in:
Alex Grönholm 2015-05-03 01:40:34 +03:00
parent f3d2563b43
commit bf9f88c28e
3 changed files with 24 additions and 10 deletions

View File

@ -3,6 +3,8 @@
- Dropped Python 2.5 and 3.1 support
- Removed the deprecated "futures" top level package
- Applied patch for issue 11777 (Executor.map does not submit futures until
iter.next() is called)
- Applied patch for issue 15015 (accessing an non-existing attribute)
- Applied patch for issue 16284 (memory leak)
- Applied patch for issue 20367 (behavior of concurrent.futures.as_completed()

View File

@ -569,15 +569,19 @@ class Executor(object):
fs = [self.submit(fn, *args) for args in zip(*iterables)]
try:
for future in fs:
if timeout is None:
yield future.result()
else:
yield future.result(end_time - time.time())
finally:
for future in fs:
future.cancel()
# Yield must be hidden in closure so that the futures are submitted
# before the first iterator value is required.
def result_iterator():
try:
for future in fs:
if timeout is None:
yield future.result()
else:
yield future.result(end_time - time.time())
finally:
for future in fs:
future.cancel()
return result_iterator()
def shutdown(self, wait=True):
"""Clean-up the resources associated with the Executor.

View File

@ -477,7 +477,15 @@ class ExecutorTest(unittest.TestCase):
class ThreadPoolExecutorTest(ThreadPoolMixin, ExecutorTest):
pass
def test_map_submits_without_iteration(self):
"""Tests verifying issue 11777."""
finished = []
def record_finished(n):
finished.append(n)
self.executor.map(record_finished, range(10))
self.executor.shutdown(wait=True)
self.assertEqual(len(finished), 10)
class ProcessPoolExecutorTest(ProcessPoolMixin, ExecutorTest):