From 08c2ba0717089662132af69bf5948d82277a8a69 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 13 Dec 2018 02:15:30 +0100 Subject: 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. --- Lib/multiprocessing/pool.py | 17 +++++++++-------- Lib/test/_test_multiprocessing.py | 16 ++++++++++++++++ .../Library/2018-12-13-00-10-51.bpo-35477.hHyy06.rst | 2 ++ 3 files changed, 27 insertions(+), 8 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2018-12-13-00-10-51.bpo-35477.hHyy06.rst diff --git a/Lib/multiprocessing/pool.py b/Lib/multiprocessing/pool.py index 2b3cc59..c077541 100644 --- a/Lib/multiprocessing/pool.py +++ b/Lib/multiprocessing/pool.py @@ -261,6 +261,10 @@ class Pool(object): self._quick_put = self._inqueue._writer.send self._quick_get = self._outqueue._reader.recv + def _check_running(self): + if self._state != RUN: + raise ValueError("Pool not running") + def apply(self, func, args=(), kwds={}): ''' Equivalent of `func(*args, **kwds)`. @@ -306,8 +310,7 @@ class Pool(object): ''' Equivalent of `map()` -- can be MUCH slower than `Pool.map()`. ''' - if self._state != RUN: - raise ValueError("Pool not running") + self._check_running() if chunksize == 1: result = IMapIterator(self._cache) self._taskqueue.put( @@ -336,8 +339,7 @@ class Pool(object): ''' Like `imap()` method but ordering of results is arbitrary. ''' - if self._state != RUN: - raise ValueError("Pool not running") + self._check_running() if chunksize == 1: result = IMapUnorderedIterator(self._cache) self._taskqueue.put( @@ -366,8 +368,7 @@ class Pool(object): ''' Asynchronous version of `apply()` method. ''' - if self._state != RUN: - raise ValueError("Pool not running") + self._check_running() result = ApplyResult(self._cache, callback, error_callback) self._taskqueue.put(([(result._job, 0, func, args, kwds)], None)) return result @@ -385,8 +386,7 @@ class Pool(object): ''' Helper function to implement map, starmap and their async counterparts. ''' - if self._state != RUN: - raise ValueError("Pool not running") + self._check_running() if not hasattr(iterable, '__len__'): iterable = list(iterable) @@ -625,6 +625,7 @@ class Pool(object): p.join() def __enter__(self): + self._check_running() return self def __exit__(self, exc_type, exc_val, exc_tb): diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index 0b0fe7c..a2dc53c 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -2561,6 +2561,22 @@ class _TestPool(BaseTestCase): # they were released too. self.assertEqual(CountedObject.n_instances, 0) + def test_enter(self): + if self.TYPE == 'manager': + self.skipTest("test not applicable to manager") + + pool = self.Pool(1) + with pool: + pass + # call pool.terminate() + # pool is no longer running + + with self.assertRaises(ValueError): + # bpo-35477: pool.__enter__() fails if the pool is not running + with pool: + pass + pool.join() + def raising(): raise KeyError("key") diff --git a/Misc/NEWS.d/next/Library/2018-12-13-00-10-51.bpo-35477.hHyy06.rst b/Misc/NEWS.d/next/Library/2018-12-13-00-10-51.bpo-35477.hHyy06.rst new file mode 100644 index 0000000..524df71 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-12-13-00-10-51.bpo-35477.hHyy06.rst @@ -0,0 +1,2 @@ +:meth:`multiprocessing.Pool.__enter__` now fails if the pool is not running: +``with pool:`` fails if used more than once. -- cgit v0.12