Skip to content

gen: accept any _Yieldable in WaitIterator constructor (issue #3001)#3670

Open
HrachShah wants to merge 1 commit into
tornadoweb:masterfrom
HrachShah:fix/wait-iterator-yieldable-typing
Open

gen: accept any _Yieldable in WaitIterator constructor (issue #3001)#3670
HrachShah wants to merge 1 commit into
tornadoweb:masterfrom
HrachShah:fix/wait-iterator-yieldable-typing

Conversation

@HrachShah

Copy link
Copy Markdown

Fixes #3001

What

WaitIterator's constructor is documented to take any awaitable
(tornado.gen.WaitIterator docstring: 'Provides an iterator to yield
the results of awaitables as they finish'), but its type annotation
pinned the parameters to Future. mypy rejected the documented usage
gen.WaitIterator(tornado.locks.Event().wait()) even though it
worked at runtime (the future_add_done_callback call inside the
constructor only worked when the input happened to already be a
Futureasyncio.Future would crash with AttributeError on
add_done_callback, and coroutines wouldn't be started at all).

The type now matches the documented behaviour: *args and
**kwargs are _Yieldable, and each input is normalized through
convert_yielded so the rest of the class can keep treating
_unfinished as dict[Future, int | str]. When the user passes
a Future, convert_yielded returns the same object
(is_future short-circuits), so the documented contract that
current_future is the input that produced the result is preserved.

Test

New WaitIteratorTest.test_iterator_accepts_coroutine in
tornado/test/gen_test.py passes three async def coroutines with
different gen.sleep delays to WaitIterator and asserts all
three values come back via current_index. On the pre-fix code
this test crashes inside the constructor with
AttributeError: 'coroutine' object has no attribute 'add_done_callback'
for the first coroutine input.

Verified with
python3 -m pytest tornado/test/gen_test.py -> 73 passed
(72 existing + 1 new). The five pre-existing
WaitIteratorTest cases still pass without modification, including
test_already_done and test_iterator which assert
current_future is f1 and friends — those inputs are Future
objects, and convert_yielded returns them unchanged.

mypy on tornado/gen.py reports no new errors (the only
diagnostic is the pre-existing missing-stubs note for pycurl in
tornado/curl_httpclient.py).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

WaitIterator constructor typing is not match with documentation

1 participant