gh-134173: optimize state transfer between concurrent.futures.Future and asyncio.Future (#134174)

Co-authored-by: Kumar Aditya <kumaraditya@python.org>
This commit is contained in:
J. Nick Koston 2025-05-18 11:56:20 -04:00 committed by GitHub
parent f2de1e6861
commit 53da1e8c8c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 148 additions and 14 deletions

View file

@ -6,6 +6,7 @@ from concurrent.futures._base import (
PENDING, RUNNING, CANCELLED, CANCELLED_AND_NOTIFIED, FINISHED, Future)
from test import support
from test.support import threading_helper
from .util import (
PENDING_FUTURE, RUNNING_FUTURE, CANCELLED_FUTURE,
@ -282,6 +283,62 @@ class FutureTests(BaseTestCase):
self.assertEqual(f.exception(), e)
def test_get_snapshot(self):
"""Test the _get_snapshot method for atomic state retrieval."""
# Test with a pending future
f = Future()
done, cancelled, result, exception = f._get_snapshot()
self.assertFalse(done)
self.assertFalse(cancelled)
self.assertIsNone(result)
self.assertIsNone(exception)
# Test with a finished future (successful result)
f = Future()
f.set_result(42)
done, cancelled, result, exception = f._get_snapshot()
self.assertTrue(done)
self.assertFalse(cancelled)
self.assertEqual(result, 42)
self.assertIsNone(exception)
# Test with a finished future (exception)
f = Future()
exc = ValueError("test error")
f.set_exception(exc)
done, cancelled, result, exception = f._get_snapshot()
self.assertTrue(done)
self.assertFalse(cancelled)
self.assertIsNone(result)
self.assertIs(exception, exc)
# Test with a cancelled future
f = Future()
f.cancel()
done, cancelled, result, exception = f._get_snapshot()
self.assertTrue(done)
self.assertTrue(cancelled)
self.assertIsNone(result)
self.assertIsNone(exception)
# Test concurrent access (basic thread safety check)
f = Future()
f.set_result(100)
results = []
def get_snapshot():
for _ in range(1000):
snapshot = f._get_snapshot()
results.append(snapshot)
threads = [threading.Thread(target=get_snapshot) for _ in range(4)]
with threading_helper.start_threads(threads):
pass
# All snapshots should be identical for a finished future
expected = (True, False, 100, None)
for result in results:
self.assertEqual(result, expected)
def setUpModule():
setup_module()