Trio 0.4.0 (2018-04-10)¶
- Add unix client socket support. (#401)
- Add support for
contextvars(see task-local storage), and add
trio.hazmat.RunVaras a similar API for run-local variables. Deprecate
trio.hazmat.RunLocalin favor of these new APIs. (#420)
trio.hazmat.current_root_task()to get the root task. (#452)
- Fix KeyboardInterrupt handling when threading state has been modified by a 3rd-party library. (#461)
Deprecations and Removals¶
Trio 0.3.0 (2017-12-28)¶
- Simplified nurseries: In Trio, the rule used to be that “parenting is a
full time job”, meaning that after a task opened a nursery and spawned some
children into it, it had to immediately block in
__aexit__to supervise the new children, or else exception propagation wouldn’t work. Also there was some elaborate machinery to let you replace this supervision logic with your own custom supervision logic. Thanks to new advances in task-rearing technology, parenting is no longer a full time job! Now the supervision happens automatically in the background, and essentially the body of a
async with trio.open_nursery()block acts just like a task running inside the nursery. This is important: it makes it possible for libraries to abstract over nursery creation. For example, if you have a Websocket library that needs to run a background task to handle Websocket pings, you can now do that with
async with open_websocket(...) as ws: ..., and that can run a task in the background without your users having to worry about parenting it. And don’t worry, you can still make custom supervisors; it turned out all that spiffy machinery was actually redundant and didn’t provide much value. (#136)
- Trio socket methods like
connectno longer require “pre-resolved” numeric addresses; you can now pass regular hostnames and Trio will implicitly resolve them for you. (#377)
- Fixed some corner cases in Trio socket method implicit name resolution to
better match stdlib behavior. Example:
sock.bind(("", port))now binds to the wildcard address instead of raising an error. (#277)
Deprecations and Removals¶
- Removed everything that was deprecated in 0.2.0; see the 0.2.0 release notes below for details.
- As was foretold in the v0.2.0 release notes, the
bindmethod on Trio sockets is now async. Please update your calls or – better yet – switch to our shiny new high-level networking API, like
resolve_remote_addressmethods on Trio sockets have been deprecated; these are unnecessary now that you can just pass your hostnames directly to the socket methods you want to use. (#377)
Trio 0.2.0 (2017-12-06)¶
Trio 0.2.0 contains changes from 14 contributors, and brings major new features and bug fixes, as well as a number of deprecations and a very small number of backwards incompatible changes. We anticipate that these should be easy to adapt to, but make sure to read about them below, and if you’re using Trio then remember to read and subscribe to issue #1.
The new nursery
start()method makes it easy to perform controlled start-up of long-running tasks. For example, given an appropriate
http_server_on_random_open_portfunction, you could write:
port = await nursery.start(http_server_on_random_open_port)
and this would start the server running in the background in the nursery, and then give you back the random port it selected – but not until it had finished initializing and was ready to accept requests!
Added a new abstract API for byte streams, and
trio.testinggained helpers for creating fake streams for testing your protocol implementation and checking that your custom stream implementation follows the stream contract.
If you’re currently using
trio.socketthen you should switch to using our new high-level networking API instead. It takes care of many tiresome details, it’s fully integrated with the abstract stream API, and it provides niceties like a state-of-the-art Happy Eyeballs implementation in
open_tcp_stream()and server helpers that integrate with
We’ve also added comprehensive support for SSL/TLS encryption, including SNI (both client and server side), STARTTLS, renegotiation during full-duplex usage (subject to OpenSSL limitations), and applying encryption to arbitrary
Streams, which allows for interesting applications like TLS-over-TLS. See:
Interesting fact: the test suite for
trio.sslhas so far found bugs in CPython’s ssl module, PyPy’s ssl module, PyOpenSSL, and OpenSSL. (
trio.ssldoesn’t use PyOpenSSL.) Trio’s test suite is fairly thorough.
Added a new guide to for contributors.
Breaking changes and deprecations¶
Trio is a young and ambitious project, but it also aims to become a stable, production-quality foundation for async I/O in Python. Therefore, our approach for now is to provide deprecation warnings where-ever possible, but on a fairly aggressive cycle as we push towards stability. If you use Trio you should read and subscribe to issue #1. We’d also welcome feedback on how this approach is working, whether our deprecation warnings could be more helpful, or anything else.
The tl;dr is: stop using
socket.bind if you can, and then fix
everything your test suite warns you about.
Upcoming breaking changes without warnings (i.e., stuff that works in 0.2.0, but won’t work in 0.3.0):
- In the next release, the
bindmethod on Trio socket objects will become async (#241). Unfortunately, there’s no good way to provide a warning here. We recommend switching to the new highlevel networking APIs like
serve_tcp(), which will insulate you from this change.
Breaking changes (i.e., stuff that could theoretically break a program that worked on 0.1.0):
trio.socketno longer attempts to normalize or modernize socket options across different platforms. The high-level networking API now handles that, freeing
trio.socketto focus on giving you raw, unadulterated BSD sockets.
- When a socket
sendallcall was cancelled, it used to attach some metadata to the exception reporting how much data was actually sent. It no longer does this, because in common configurations like an
SSLStreamwrapped around a
SocketStreamit becomes ambiguous which “level” the partial metadata applies to, leading to confusion and bugs. There is no longer any way to tell how much data was sent after a
trio.socket.getprotobyname()function is now async, like it should have been all along. I doubt anyone will ever use it, but that’s no reason not to get the details right.
getfqdnhave been removed, because they were obscure, buggy, and obsolete. Use
Upcoming breaking changes with warnings (i.e., stuff that in 0.2.0 will work but will print loud complaints, and that won’t work in 0.3.0):
For consistency with the new
startmethod, the nursery
spawnmethod is being renamed to
trio.socket.sendallis deprecated; use
Trio now consistently uses
runfor functions that take and run an async function (like
run_syncfor functions that take and run a synchronous function. As part of this:
- We took the opportunity to refactor
await_in_trio_threadinto the new class
- The hazmat function
current_call_soon_thread_and_signal_safeis being replaced by
See #68 for details.
Trio 0.1.0 provided a set of built-in mechanisms for waiting for and tracking the result of individual tasks. We haven’t yet found any cases where using this actually led to simpler code, though, and this feature is blocking useful improvements, so the following are being deprecated without replacement:
In addition, several introspection attributes are being renamed:
See #136 for more details.
To consolidate introspection functionality in
trio.hazmat, the following functions are moving:
See #317 for more details.
In addition, the following functions in
trio.testingare changing names:
See #157 for more details.
Unfortunately, a limitation in PyPy3 5.8 breaks our deprecation handling for some renames. (Attempting to use the old names will give an unhelpful error instead of a helpful warning.) This does not affect CPython, or PyPy3 5.9+.
New support for tests to cleanly hook hostname lookup and socket operations: see Virtual networking for testing. In addition,
trio.socket.SocketTypeis now an empty abstract base class, with the actual socket class made private. This shouldn’t effect anyone, since the only thing you could directly use it for in the first place was
isinstancechecks, and those still work (#170)
It’s generally true that if you’re using Trio you have to use Trio functions, if you’re using asyncio you have to use asyncio functions, and so forth. (See the discussion of the “async sandwich” in the Trio tutorial for more details.) So for example, this isn’t going to work:
async def main(): # asyncio here await asyncio.sleep(1) # trio here trio.run(main)
Trio now reliably detects if you accidentally do something like this, and gives a helpful error message.
Trio now also has special error messages for several other common errors, like doing
Instrumentraises an unexpected error, we now route it through the
loggingmodule instead of printing it directly to stderr. Normally this produces exactly the same effect, but this way it’s more configurable. (#306)
Fixed a minor race condition in IOCP thread shutdown on Windows (#81)
trio.run()takes a new keyword argument
New attributes allow more detailed introspection of the task tree:
trio.testing.wait_all_tasks_blocked()now takes a
tiebreaker=argument. The main use is to allow
MockClock’s auto-jump functionality to avoid interfering with direct use of
wait_all_tasks_blocked()in the same test.
sock.accept()for IPv6 sockets (#164)
Trio now uses yapf to standardize formatting across the source tree, so we never have to think about whitespace again.
Many documentation improvements
Trio 0.1.0 (2017-03-10)¶
- Initial release.