Release history¶
trio-asyncio 0.13.0 (2023-12-01)¶
Features¶
Exiting an
async with trio_asyncio.open_loop():
block now cancels any asyncio tasks that are still running in the background, likeasyncio.run()
does, so that they have a chance to clean up resources by running async context managers andfinally
blocks. Previously such tasks would simply be abandoned to the garbage collector, resulting in potential deadlocks and stderr spew. Note that, likeasyncio.run()
, we do still abandon any tasks that are started during this finalization phase and outlive the existing tasks. (#91)
Bugfixes¶
A deadlock will no longer occur if
trio_asyncio.open_loop()
is cancelled before its first checkpoint. We also now cancel and wait on all asyncio tasks even ifopen_loop()
terminates due to an exception that was raised within theasync with
block. (#115)Uncaught exceptions from asyncio tasks will now propagate out of the
trio_asyncio.open_loop()
call. This has always been the documented behavior, but didn’t actually work before. (#121)Use of
loop.add_reader()
orloop.add_writer()
with a socket object (rather than a file descriptor) will no longer potentially produce spurious uncaught exceptions if the socket is closed in the reader/writer callback. (#121)
Miscellaneous¶
trio-asyncio
now requires Trio 0.22 and does not produce deprecation warnings. Python 3.12 is now supported. Python 3.6 and 3.7 are no longer supported. (#121)trio-asyncio now indicates its presence to
sniffio
using thesniffio.thread_local
interface that is preferred since sniffio v1.3.0. This should be less likely than the previous approach to causesniffio.current_async_library()
to return incorrect results due to unintended inheritance of contextvars. (#123)
trio-asyncio 0.12.0 (2021-01-07)¶
Bugfixes¶
trio-asyncio now cancels any Trio tasks that were started inside a trio-asyncio loop (using e.g.
trio_as_aio()
) before it allows the trio-asyncio loop to close. This should resolve some cases of deadlocks and “RuntimeError: Event loop is closed” when anasync with open_loop():
block is cancelled. (#89)asyncio.get_running_loop()
will now return the trio-asyncio event loop (if running), instead of failing withRuntimeError
. (#99)On Python versions with native contextvars support (3.7+), a Trio task started from asyncio context (using
trio_as_aio()
,trio_as_future()
, etc) will now properly inherit the contextvars of its caller. Also, if the entire trio-asyncio loop is cancelled, such tasks will no longer lettrio.Cancelled
exceptions leak into their asyncio caller. (#76)Previously, cancelling the context surrounding an
open_loop()
block might cause a deadlock in some cases. The ordering of operations during loop teardown has been improved, so this shouldn’t happen anymore. (#81)
Deprecations and Removals¶
A number of functions deprecated since 0.10.0 are now removed:
Removed |
Replacement |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Miscellaneous¶
trio-asyncio 0.11.0 (2020-03-09)¶
Features¶
Substantially reorganize monkeypatching for asyncio event loop and event loop policy accessors, fixing support for Python 3.8. Also, stop using features deprecated in Trio 0.12. (#66)
Bugfixes¶
Calling
loop.stop
manually no longer causes a deadlock when exiting the context oftrio_asyncio.open_loop
(#58)trio_asyncio.run()
now properly returns whatever was returned by the async function it ran, liketrio.run()
does. (#57)Replace uses of deprecated
trio.open_cancel_scope()
withtrio.CancelScope
.
Deprecations and Removals¶
The non-underscore-prefixed names of trio-asyncio submodules (
trio_asyncio.loop
,trio_asyncio.adapter
, etc) have been deprecated; public names should be imported fromtrio_asyncio
directly.trio_asyncio.current_policy
,trio_asyncio.TrioChildWatcher
, andtrio_asyncio.TrioPolicy
have been deprecated with no replacement.current_policy
is no longer used at all, and the other two are singletons that can’t be customized so there’s no reason to make them publicly visible.A number of functions which were already documented as deprecated now raise the new
TrioAsyncioDeprecationWarning
where previously they provided either no runtime warning or a genericDeprecationWarning
. (#64)
trio-asyncio 0.10.0 (2018-12-09)¶
Bugfixes¶
Replace deprecated
trio.Queue
with new channels, requiring Trio 0.9 or later. (#49)
trio-asyncio 0.9.1 (2018-09-06)¶
Bugfixes¶
Defer creating an asyncio coroutine until asyncio mode is actually entered. (#40)
trio-asyncio 0.9.0 (2018-08-31)¶
Features¶
Major reorganization: The main entry point for calling asyncio from trio is now the
trio_asyncio.aio_as_trio()
adapter. Instead of callingasyncio.get_event_loop()
, directly access the contextvartrio_aio_loop
(akatrio_asyncio.current_loop
). (#36)
Deprecations and Removals¶
run_asyncio()
is deprecated: replace with aaio_as_trio()
wrapper.trio2aio()
is deprecated: replace withaio_as_trio()
.run_future()
andTrioEventLoop.run_future()
are deprecated: replace withrun_aio_future()
.run_coroutine()
andTrioEventLoop.run_coroutine()
are deprecated: replace withrun_aio_coroutine()
.TrioEventLoop.wrap_generator()
is deprecated: replace with aaio_as_trio()
wrapper.TrioEventLoop.run_iterator()
is deprecated: replace withaio_as_trio()
. (#36)
trio-asyncio 0.8.2 (2018-08-25)¶
Features¶
sniffio.current_async_library()
in a trio-asyncio program now returns the correct value for the current mode ("trio"
or"asyncio"
).
trio-asyncio 0.8.1 (2018-08-25)¶
Features¶
trio_asyncio
now contains anallow_asyncio()
wrapper which allows you to seamlessly mix asyncio and trio semantics:import asyncio import trio from trio_asyncio import run, allow_asyncio async def main(): print("Sleeping 1") await asyncio.sleep(1) print("Sleeping 2") await trio.sleep(1) run(allow_asyncio, main)
The problem with this solution is that Trio’s cancellations will no longer be converted to asyncio’s
CancelledError
within asyncio code. This may or may not be an issue for your code. (#30)While the test suite still requires Python 3.6,
trio_asyncio
itself now works on Python 3.5.3 and later. (#33)TrioEventLoop.run_asyncio()
now supports wrapping async iterators and async context managers, in addition to its existing support for async functions.
trio-asyncio 0.8.0 (2018-08-03)¶
Add
TrioEventLoop.run_iterator()
as an alias forrun_generator()
.Add support for Python 3.7 via a monkey-patch to
asyncio.set_event_loop_policy()
. (#23)Deprecate the use of “compatibility mode” / “sync event loops”, except as a tool for running the test suites of existing asyncio projects.
trio-asyncio 0.7.5 (2018-07-23)¶
Use a contextvar to represent the current trio-asyncio loop, rather than the deprecated
trio.TaskLocal
.Use the
outcome
library rather than the deprecatedtrio.hazmat.Result
.Better handle errors in wrapped async generators.
trio-asyncio 0.7.0 (2018-03-27)¶
The
@trio2aio
and@aio2trio
decorators now can be used to decorate both async generator functions and async functions that take keyword arguments.open_loop()
now takes an optionalqueue_len=
parameter to specify the length of the internal callback queue (for performance tuning).Monkey-patch
asyncio.get_event_loop_policy()
andasyncio.get_event_loop()
so trio-asyncio works correctly in multithreaded programs that use a different asyncio event loop in other threads.Add
wrap_generator()
andrun_generator()
which adapt an asyncio-flavored async generator to be used from Trio code.
trio-asyncio 0.5.0 (2018-02-20)¶
Support contextvars on Python 3.7 and later.
Support waiting for child processes even though Trio doesn’t (yet).
trio-asyncio 0.4.2 (2018-02-12)¶
Add
trio_asyncio.run()
.Fix a deadlock in
SyncTrioEventLoop
. Encourage people to use the asyncTrioEventLoop
instead.
trio-asyncio 0.4.1 (2018-02-08)¶
Add
TrioEventLoop.run_task()
as an entry point for running Trio code in a context that allows asyncio calls, for use when neither a Trio nor an asyncio event loop is running.
trio-asyncio 0.4.0 (2018-02-07)¶
Add support for async loops (
open_loop()
) and encourage their use. Numerous functions renamed.
trio-asyncio 0.3.0 (2017-10-17)¶
Initial release.