]> granicus.if.org Git - python/commitdiff
Issue #11777: Executor.map does not submit futures until iter.next() is called
authorBrian Quinlan <brian@sweetapp.com>
Thu, 7 Apr 2011 22:19:33 +0000 (08:19 +1000)
committerBrian Quinlan <brian@sweetapp.com>
Thu, 7 Apr 2011 22:19:33 +0000 (08:19 +1000)
Lib/concurrent/futures/_base.py
Lib/test/test_concurrent_futures.py

index 79b91d495fca987366c9b64a952e361a4e49a0d5..6cfded307555a3a24989129f121e59ac8e027c84 100644 (file)
@@ -536,15 +536,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.
index 2662af76cff82d8ac48942d1a6bc008c4c9c33da..ec84a663079d3f9841147d5b0e2440626704407e 100644 (file)
@@ -369,7 +369,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.assertCountEqual(finished, range(10))
 
 
 class ProcessPoolExecutorTest(ProcessPoolMixin, ExecutorTest):