[Python-checkins] cpython: Issue #11777: Executor.map does not submit futures until iter.next() is called

brian.quinlan python-checkins at python.org
Fri Apr 8 00:30:58 CEST 2011


http://hg.python.org/cpython/rev/126353bc7e94
changeset:   69192:126353bc7e94
parent:      69181:11052e067192
user:        Brian Quinlan <brian at sweetapp.com>
date:        Fri Apr 08 08:19:33 2011 +1000
summary:
  Issue #11777: Executor.map does not submit futures until iter.next() is called

files:
  Lib/concurrent/futures/_base.py     |  22 ++++++++++------
  Lib/test/test_concurrent_futures.py |  10 ++++++-
  2 files changed, 22 insertions(+), 10 deletions(-)


diff --git a/Lib/concurrent/futures/_base.py b/Lib/concurrent/futures/_base.py
--- a/Lib/concurrent/futures/_base.py
+++ b/Lib/concurrent/futures/_base.py
@@ -536,15 +536,19 @@
 
         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.
diff --git a/Lib/test/test_concurrent_futures.py b/Lib/test/test_concurrent_futures.py
--- a/Lib/test/test_concurrent_futures.py
+++ b/Lib/test/test_concurrent_futures.py
@@ -369,7 +369,15 @@
 
 
 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.assertCountEqual(finished, range(10))
 
 
 class ProcessPoolExecutorTest(ProcessPoolMixin, ExecutorTest):

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list