Skip to content

Commit

Permalink
concurrent: Update type hint on chain_future to match implementation
Browse files Browse the repository at this point in the history
This method has always accepted both asyncio and concurrent futures,
but the type hint incorrectly indicated that it only accepted asyncio
futures.

Fixes #3314
  • Loading branch information
bdarnell committed Jun 7, 2024
1 parent 4337efe commit 385af83
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 1 deletion.
5 changes: 4 additions & 1 deletion tornado/concurrent.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,10 @@ def wrapper(self: Any, *args: Any, **kwargs: Any) -> Future:
_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
Expand Down
26 changes: 26 additions & 0 deletions tornado/test/concurrent_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

from tornado.concurrent import (
Future,
chain_future,
run_on_executor,
future_set_result_unless_cancelled,
)
Expand All @@ -47,6 +48,31 @@ def test_future_set_result_unless_cancelled(self):
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.

Expand Down

0 comments on commit 385af83

Please sign in to comment.