Issue #20980: Stop wrapping exception when using ThreadPool.

This commit is contained in:
Richard Oudkerk 2014-03-23 12:30:54 +00:00
parent a40675a1a2
commit 80a5be1d84
4 changed files with 30 additions and 6 deletions

View File

@ -1077,17 +1077,22 @@ ArrayProxy = MakeProxyType('ArrayProxy', (
)) ))
PoolProxy = MakeProxyType('PoolProxy', ( BasePoolProxy = MakeProxyType('PoolProxy', (
'apply', 'apply_async', 'close', 'imap', 'imap_unordered', 'join', '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', 'apply_async': 'AsyncResult',
'map_async': 'AsyncResult', 'map_async': 'AsyncResult',
'starmap_async': 'AsyncResult', 'starmap_async': 'AsyncResult',
'imap': 'Iterator', 'imap': 'Iterator',
'imap_unordered': '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 # Definition of SyncManager

View File

@ -90,7 +90,8 @@ class MaybeEncodingError(Exception):
return "<MaybeEncodingError: %s>" % str(self) 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) assert maxtasks is None or (type(maxtasks) == int and maxtasks > 0)
put = outqueue.put put = outqueue.put
get = inqueue.get get = inqueue.get
@ -117,7 +118,8 @@ def worker(inqueue, outqueue, initializer=None, initargs=(), maxtasks=None):
try: try:
result = (True, func(*args, **kwds)) result = (True, func(*args, **kwds))
except Exception as e: except Exception as e:
e = ExceptionWithTraceback(e, e.__traceback__) if wrap_exception:
e = ExceptionWithTraceback(e, e.__traceback__)
result = (False, e) result = (False, e)
try: try:
put((job, i, result)) put((job, i, result))
@ -137,6 +139,8 @@ class Pool(object):
''' '''
Class which supports an async version of applying functions to arguments. Class which supports an async version of applying functions to arguments.
''' '''
_wrap_exception = True
def Process(self, *args, **kwds): def Process(self, *args, **kwds):
return self._ctx.Process(*args, **kwds) return self._ctx.Process(*args, **kwds)
@ -220,7 +224,8 @@ class Pool(object):
w = self.Process(target=worker, w = self.Process(target=worker,
args=(self._inqueue, self._outqueue, args=(self._inqueue, self._outqueue,
self._initializer, self._initializer,
self._initargs, self._maxtasksperchild) self._initargs, self._maxtasksperchild,
self._wrap_exception)
) )
self._pool.append(w) self._pool.append(w)
w.name = w.name.replace('Process', 'PoolWorker') w.name = w.name.replace('Process', 'PoolWorker')
@ -736,6 +741,7 @@ class IMapUnorderedIterator(IMapIterator):
# #
class ThreadPool(Pool): class ThreadPool(Pool):
_wrap_exception = False
@staticmethod @staticmethod
def Process(*args, **kwds): def Process(*args, **kwds):

View File

@ -1810,6 +1810,17 @@ class _TestPool(BaseTestCase):
self.assertIn('raise RuntimeError(123) # some comment', self.assertIn('raise RuntimeError(123) # some comment',
f1.getvalue()) 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(): def raising():
raise KeyError("key") raise KeyError("key")

View File

@ -21,6 +21,8 @@ Core and Builtins
Library Library
------- -------
- Issue #20980: Stop wrapping exception when using ThreadPool.
- Issue #20990: Fix issues found by pyflakes for multiprocessing. - Issue #20990: Fix issues found by pyflakes for multiprocessing.
- Issue #21015: SSL contexts will now automatically select an elliptic - Issue #21015: SSL contexts will now automatically select an elliptic