From: Ben Darnell Date: Fri, 7 Jun 2024 19:54:08 +0000 (-0400) Subject: concurrent: Update type hint on chain_future to match implementation X-Git-Tag: v6.5.0b1~58^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=385af837f278ec0a6489cb61db158960e648fa94;p=thirdparty%2Ftornado.git concurrent: Update type hint on chain_future to match implementation This method has always accepted both asyncio and concurrent futures, but the type hint incorrectly indicated that it only accepted asyncio futures. Fixes #3314 --- diff --git a/tornado/concurrent.py b/tornado/concurrent.py index 5047c538..e98093f2 100644 --- a/tornado/concurrent.py +++ b/tornado/concurrent.py @@ -145,7 +145,10 @@ def run_on_executor(*args: Any, **kwargs: Any) -> Callable: _NO_RESULT = object() -def chain_future(a: "Future[_T]", b: "Future[_T]") -> None: +def chain_future( + a: Union["Future[_T]", "futures.Future[_T]"], + b: Union["Future[_T]", "futures.Future[_T]"], +) -> None: """Chain two futures together so that when one completes, so does the other. The result (success or failure) of ``a`` will be copied to ``b``, unless diff --git a/tornado/test/concurrent_test.py b/tornado/test/concurrent_test.py index 33fcb650..009d6ed4 100644 --- a/tornado/test/concurrent_test.py +++ b/tornado/test/concurrent_test.py @@ -21,6 +21,7 @@ import unittest from tornado.concurrent import ( Future, + chain_future, run_on_executor, future_set_result_unless_cancelled, ) @@ -47,6 +48,31 @@ class MiscFutureTest(AsyncTestCase): self.assertEqual(fut.result(), 42) +class ChainFutureTest(AsyncTestCase): + @gen_test + async def test_asyncio_futures(self): + fut: Future[int] = Future() + fut2: Future[int] = Future() + chain_future(fut, fut2) + fut.set_result(42) + result = await fut2 + self.assertEqual(result, 42) + + @gen_test + async def test_concurrent_futures(self): + # A three-step chain: two concurrent futures (showing that both arguments to chain_future + # can be concurrent futures), and then one from a concurrent future to an asyncio future so + # we can use it in await. + fut: futures.Future[int] = futures.Future() + fut2: futures.Future[int] = futures.Future() + fut3: Future[int] = Future() + chain_future(fut, fut2) + chain_future(fut2, fut3) + fut.set_result(42) + result = await fut3 + self.assertEqual(result, 42) + + # The following series of classes demonstrate and test various styles # of use, with and without generators and futures.