Improve asyncio support to avoid hangs of asyncio.sleep() #470
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Clean up asyncio tests
We finish the cleanup of
test_asyncio.py
done in c60dd14and in 204647b by removing remnants of support of Pythons with no
asyncio
module because all Python interpreters supported by freezegunalready support
asyncio
.Avoid
asyncio.sleep()
hanging forever when time is frozenThe following code:
hangs forever since FreezeGun 1.1.0 because 1.1.0 started patching
time.monotonic()
(see #369) which is used internally byasyncio
event loops to schedule code for execution in the future. This breaks
many projects that uses FreezeGun to test asynchronous code.
We fix this by changing
freeze_time
to patch asyncio event loop'stime()
method in a way that it uses real monotonic time instead of thefrozen one. Note that we couldn't achieve this by adding
asyncio
toDEFAULT_IGNORE_LIST
infreezegun/config.py
because any running asynccode has functions from the
asyncio
module on its stack -- addingasyncio
to the ignore list would just disable freezing time in anyasync code. This is why we patch one method of a specific class instead.
This change not only fixes
asyncio.sleep()
but also things likeasyncio.get_running_loop().call_later
(for scheduling task executionin the future) which in turn makes things like timeouts work in async
code while time is frozen. This may not be desired because some users
may expect that execution of events scheduled to happen in the future
can be controlled using FreezeGun. However, it's not easy to distinguish
between things that users would like to see frozen time and those which
should not (like
asyncio.sleep()
) because all of them use the sameclock. Therefore, we opt for making all
asyncio
internals not affectedby FreezeGun.
We also add more tests that verify how FreezeGun interacts with asyncio
code, including tests that cover the scenario described in #437 which we
aim to fix.
Closes #401
Closes #437