Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 08c2ba0

Browse files
authored
bpo-35477: multiprocessing.Pool.__enter__() fails if called twice (GH-11134)
multiprocessing.Pool.__enter__() now fails if the pool is not running: "with pool:" fails if used more than once.
1 parent 502fe19 commit 08c2ba0

3 files changed

Lines changed: 27 additions & 8 deletions

File tree

Lib/multiprocessing/pool.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,10 @@ def _setup_queues(self):
261261
self._quick_put = self._inqueue._writer.send
262262
self._quick_get = self._outqueue._reader.recv
263263

264+
def _check_running(self):
265+
if self._state != RUN:
266+
raise ValueError("Pool not running")
267+
264268
def apply(self, func, args=(), kwds={}):
265269
'''
266270
Equivalent of `func(*args, **kwds)`.
@@ -306,8 +310,7 @@ def imap(self, func, iterable, chunksize=1):
306310
'''
307311
Equivalent of `map()` -- can be MUCH slower than `Pool.map()`.
308312
'''
309-
if self._state != RUN:
310-
raise ValueError("Pool not running")
313+
self._check_running()
311314
if chunksize == 1:
312315
result = IMapIterator(self._cache)
313316
self._taskqueue.put(
@@ -336,8 +339,7 @@ def imap_unordered(self, func, iterable, chunksize=1):
336339
'''
337340
Like `imap()` method but ordering of results is arbitrary.
338341
'''
339-
if self._state != RUN:
340-
raise ValueError("Pool not running")
342+
self._check_running()
341343
if chunksize == 1:
342344
result = IMapUnorderedIterator(self._cache)
343345
self._taskqueue.put(
@@ -366,8 +368,7 @@ def apply_async(self, func, args=(), kwds={}, callback=None,
366368
'''
367369
Asynchronous version of `apply()` method.
368370
'''
369-
if self._state != RUN:
370-
raise ValueError("Pool not running")
371+
self._check_running()
371372
result = ApplyResult(self._cache, callback, error_callback)
372373
self._taskqueue.put(([(result._job, 0, func, args, kwds)], None))
373374
return result
@@ -385,8 +386,7 @@ def _map_async(self, func, iterable, mapper, chunksize=None, callback=None,
385386
'''
386387
Helper function to implement map, starmap and their async counterparts.
387388
'''
388-
if self._state != RUN:
389-
raise ValueError("Pool not running")
389+
self._check_running()
390390
if not hasattr(iterable, '__len__'):
391391
iterable = list(iterable)
392392

@@ -625,6 +625,7 @@ def _terminate_pool(cls, taskqueue, inqueue, outqueue, pool,
625625
p.join()
626626

627627
def __enter__(self):
628+
self._check_running()
628629
return self
629630

630631
def __exit__(self, exc_type, exc_val, exc_tb):

Lib/test/_test_multiprocessing.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2561,6 +2561,22 @@ def test_release_task_refs(self):
25612561
# they were released too.
25622562
self.assertEqual(CountedObject.n_instances, 0)
25632563

2564+
def test_enter(self):
2565+
if self.TYPE == 'manager':
2566+
self.skipTest("test not applicable to manager")
2567+
2568+
pool = self.Pool(1)
2569+
with pool:
2570+
pass
2571+
# call pool.terminate()
2572+
# pool is no longer running
2573+
2574+
with self.assertRaises(ValueError):
2575+
# bpo-35477: pool.__enter__() fails if the pool is not running
2576+
with pool:
2577+
pass
2578+
pool.join()
2579+
25642580

25652581
def raising():
25662582
raise KeyError("key")
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
:meth:`multiprocessing.Pool.__enter__` now fails if the pool is not running:
2+
``with pool:`` fails if used more than once.

0 commit comments

Comments
 (0)