gh-125864: Propagate `pickle.loads()` failures in `InterpreterPoolExecutor` (gh-125898)

Authored-by: Peter Bierma <zintensitydev@gmail.com>
This commit is contained in:
Peter Bierma 2024-10-24 12:51:45 -04:00 committed by GitHub
parent 3c4a7fa617
commit 41bd9d959c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 20 additions and 1 deletions

View File

@ -107,7 +107,8 @@ class WorkerContext(_thread.WorkerContext):
@classmethod @classmethod
def _call_pickled(cls, pickled, resultsid): def _call_pickled(cls, pickled, resultsid):
fn, args, kwargs = pickle.loads(pickled) with cls._capture_exc(resultsid):
fn, args, kwargs = pickle.loads(pickled)
cls._call(fn, args, kwargs, resultsid) cls._call(fn, args, kwargs, resultsid)
def __init__(self, initdata, shared=None): def __init__(self, initdata, shared=None):

View File

@ -56,6 +56,16 @@ class InterpretersMixin(InterpreterPoolMixin):
return r, w return r, w
class PickleShenanigans:
"""Succeeds with pickle.dumps(), but fails with pickle.loads()"""
def __init__(self, value):
if value == 1:
raise RuntimeError("gotcha")
def __reduce__(self):
return (self.__class__, (1,))
class InterpreterPoolExecutorTest( class InterpreterPoolExecutorTest(
InterpretersMixin, ExecutorTest, BaseTestCase): InterpretersMixin, ExecutorTest, BaseTestCase):
@ -279,6 +289,14 @@ class InterpreterPoolExecutorTest(
self.assertEqual(len(executor._threads), 1) self.assertEqual(len(executor._threads), 1)
executor.shutdown(wait=True) executor.shutdown(wait=True)
def test_pickle_errors_propagate(self):
# GH-125864: Pickle errors happen before the script tries to execute, so the
# queue used to wait infinitely.
fut = self.executor.submit(PickleShenanigans(0))
with self.assertRaisesRegex(RuntimeError, "gotcha"):
fut.result()
class AsyncioTest(InterpretersMixin, testasyncio_utils.TestCase): class AsyncioTest(InterpretersMixin, testasyncio_utils.TestCase):