]> granicus.if.org Git - python/commitdiff
Issue #20980: Stop wrapping exception when using ThreadPool.
authorRichard Oudkerk <shibturn@gmail.com>
Sun, 23 Mar 2014 12:30:54 +0000 (12:30 +0000)
committerRichard Oudkerk <shibturn@gmail.com>
Sun, 23 Mar 2014 12:30:54 +0000 (12:30 +0000)
Lib/multiprocessing/managers.py
Lib/multiprocessing/pool.py
Lib/test/_test_multiprocessing.py
Misc/NEWS

index cc87d36612d684f7b39f57248b4d55101d241691..66d46fcc2a9066d092c834efc05ce71e97279661 100644 (file)
@@ -1077,17 +1077,22 @@ ArrayProxy = MakeProxyType('ArrayProxy', (
     ))
 
 
-PoolProxy = MakeProxyType('PoolProxy', (
+BasePoolProxy = MakeProxyType('PoolProxy', (
     'apply', 'apply_async', 'close', 'imap', 'imap_unordered', 'join',
-    'map', 'map_async', 'starmap', 'starmap_async', 'terminate'
+    'map', 'map_async', 'starmap', 'starmap_async', 'terminate',
     ))
-PoolProxy._method_to_typeid_ = {
+BasePoolProxy._method_to_typeid_ = {
     'apply_async': 'AsyncResult',
     'map_async': 'AsyncResult',
     'starmap_async': 'AsyncResult',
     'imap': 'Iterator',
     'imap_unordered': 'Iterator'
     }
+class PoolProxy(BasePoolProxy):
+    def __enter__(self):
+        return self
+    def __exit__(self, exc_type, exc_val, exc_tb):
+        self.terminate()
 
 #
 # Definition of SyncManager
index 74d08756ed5faca87ea1a8a4eae445884f25eed8..8832a5ceb25f84d00d847c763b53bd63cb8c6b04 100644 (file)
@@ -90,7 +90,8 @@ class MaybeEncodingError(Exception):
         return "<MaybeEncodingError: %s>" % str(self)
 
 
-def worker(inqueue, outqueue, initializer=None, initargs=(), maxtasks=None):
+def worker(inqueue, outqueue, initializer=None, initargs=(), maxtasks=None,
+           wrap_exception=False):
     assert maxtasks is None or (type(maxtasks) == int and maxtasks > 0)
     put = outqueue.put
     get = inqueue.get
@@ -117,7 +118,8 @@ def worker(inqueue, outqueue, initializer=None, initargs=(), maxtasks=None):
         try:
             result = (True, func(*args, **kwds))
         except Exception as e:
-            e = ExceptionWithTraceback(e, e.__traceback__)
+            if wrap_exception:
+                e = ExceptionWithTraceback(e, e.__traceback__)
             result = (False, e)
         try:
             put((job, i, result))
@@ -137,6 +139,8 @@ class Pool(object):
     '''
     Class which supports an async version of applying functions to arguments.
     '''
+    _wrap_exception = True
+
     def Process(self, *args, **kwds):
         return self._ctx.Process(*args, **kwds)
 
@@ -220,7 +224,8 @@ class Pool(object):
             w = self.Process(target=worker,
                              args=(self._inqueue, self._outqueue,
                                    self._initializer,
-                                   self._initargs, self._maxtasksperchild)
+                                   self._initargs, self._maxtasksperchild,
+                                   self._wrap_exception)
                             )
             self._pool.append(w)
             w.name = w.name.replace('Process', 'PoolWorker')
@@ -736,6 +741,7 @@ class IMapUnorderedIterator(IMapIterator):
 #
 
 class ThreadPool(Pool):
+    _wrap_exception = False
 
     @staticmethod
     def Process(*args, **kwds):
index 8eb57fe87e7a6548117a30f21144b16452bc7470..44d6c71e408d06b83264b6fcd30c5f828397f793 100644 (file)
@@ -1810,6 +1810,17 @@ class _TestPool(BaseTestCase):
             self.assertIn('raise RuntimeError(123) # some comment',
                           f1.getvalue())
 
+    @classmethod
+    def _test_wrapped_exception(cls):
+        raise RuntimeError('foo')
+
+    def test_wrapped_exception(self):
+        # Issue #20980: Should not wrap exception when using thread pool
+        with self.Pool(1) as p:
+            with self.assertRaises(RuntimeError):
+                p.apply(self._test_wrapped_exception)
+
+
 def raising():
     raise KeyError("key")
 
index 2f9afb96988774bd59b7a79e1a582d5ff775c0af..5ec11eb8a8990f753f182065b72a5b9ec7f1597a 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -21,6 +21,8 @@ Core and Builtins
 Library
 -------
 
+- Issue #20980: Stop wrapping exception when using ThreadPool.
+
 - Issue #20990: Fix issues found by pyflakes for multiprocessing.
 
 - Issue #21015: SSL contexts will now automatically select an elliptic