Release history¶
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.
Highlights¶
Added a comprehensive API for async filesystem I/O: see Asynchronous filesystem I/O (gh-20)
The new nursery
start()
method makes it easy to perform controlled start-up of long-running tasks. For example, given an appropriatehttp_server_on_random_open_port
function, 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.testing
gained helpers for creating fake streams for testing your protocol implementations and checking that your custom stream implementations follow the abstract contract.If you’re currently using
trio.socket
then 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 inopen_tcp_stream()
and server helpers that integrate withnursery.start
.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
Stream
s, which allows for interesting applications like TLS-over-TLS. See:trio.open_ssl_over_tcp_stream()
,trio.serve_ssl_over_tcp()
,trio.open_ssl_over_tcp_listeners()
, andtrio.ssl
.Interesting fact: the test suite for
trio.ssl
has so far found bugs in CPython’s ssl module, PyPy’s ssl module, PyOpenSSL, and OpenSSL. (trio.ssl
doesn’t use PyOpenSSL.) Trio’s test suite is fairly thorough.You know thread-local storage? Well, Trio now has an equivalent: task-local storage. There’s also the related, but more obscure, run-local storage; see
RunLocal
. (#2)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
bind
method 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 likeserve_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.socket
no longer attempts to normalize or modernize socket options across different platforms. The high-level networking API now handles that, freeingtrio.socket
to focus on giving you raw, unadulterated BSD sockets.- When a socket
sendall
call 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 anSSLStream
wrapped around aSocketStream
it 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 asendall
is cancelled. - The
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. - The
trio.socket
functionsgetservbyport
,getservbyname
, andgetfqdn
have been removed, because they were obscure, buggy, and obsolete. Usegetaddrinfo()
instead.
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
start
method, the nurseryspawn
method is being renamed tostart_soon
(#284)trio.socket.sendall
is deprecated; usetrio.open_tcp_stream
andSocketStream.send_all
instead (#291)Trio now consistently uses
run
for functions that take and run an async function (liketrio.run()
!), andrun_sync
for functions that take and run a synchronous function. As part of this:run_in_worker_thread
is becomingrun_sync_in_worker_thread()
- We took the opportunity to refactor
run_in_trio_thread
andawait_in_trio_thread
into the new classtrio.BlockingTrioPortal
- The hazmat function
current_call_soon_thread_and_signal_safe
is being replaced bytrio.hazmat.TrioToken
See #68 for details.
trio.Queue
’sjoin
andtask_done
methods are deprecated without replacement (#321)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:
nursery.zombies
nursery.monitor
nursery.reap
nursery.reap_and_unwrap
task.result
task.add_monitor
task.discard_monitor
task.wait
This also lets us move a number of lower-level features out of the main
trio
namespace and intotrio.hazmat
:trio.Task
→trio.hazmat.Task
trio.current_task
→trio.hazmat.current_task()
trio.Result
→trio.hazmat.Result
trio.Value
→trio.hazmat.Value
trio.Error
→trio.hazmat.Error
trio.UnboundedQueue
→trio.hazmat.UnboundedQueue
In addition, several introspection attributes are being renamed:
nursery.children
→nursery.child_tasks
task.parent_task
→ usetask.parent_nursery.parent_task
instead
See #136 for more details.
To consolidate introspection functionality in
trio.hazmat
, the following functions are moving:trio.current_clock
→trio.hazmat.current_clock()
trio.current_statistics
→ func:trio.hazmat.current_statistics
See #317 for more details.
It was decided that 0.1.0’s “yield point” terminology was confusing; we now use “checkpoint” instead. As part of this, the following functions in
trio.hazmat
are changing names:yield_briefly
→checkpoint()
yield_briefly_no_cancel
→cancel_shielded_checkpoint()
yield_if_cancelled
→checkpoint_if_cancelled()
yield_indefinitely
→wait_task_rescheduled()
In addition, the following functions in
trio.testing
are changing names:assert_yields
→assert_checkpoints()
assert_no_yields
→assert_no_checkpoints()
See #157 for more details.
trio.format_exception
is deprecated; usetraceback.format_exception()
instead (#347).trio.current_instruments
is deprecated. For adding or removing instrumentation at run-time, seetrio.hazmat.add_instrument()
andtrio.hazmat.remove_instrument()
(#257)
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+.
Other changes¶
run_sync_in_worker_thread()
now has a robust mechanism for applying capacity limits to the number of concurrent threads (#10, #57, #156)New support for tests to cleanly hook hostname lookup and socket operations: see Virtual networking for testing. In addition,
trio.socket.SocketType
is 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 wasisinstance
checks, and those still work (#170)New class
StrictFIFOLock
New exception
ResourceBusyError
The
trio.hazmat.ParkingLot
class (which is used to implement many of Trio’s synchronization primitives) was rewritten to be simpler and faster (#272, #287)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
trio.run(some_func())
(should betrio.run(some_func)
).trio.socket
now handles non-ascii domain names using the modern IDNA 2008 standard instead of the obsolete IDNA 2003 standard (#11)When an
Instrument
raises an unexpected error, we now route it through thelogging
module 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)
Control-C handling on Windows now uses
signal.set_wakeup_fd()
and should be more reliable (#42)trio.run()
takes a new keyword argumentrestrict_keyboard_interrupt_to_checkpoints
New attributes allow more detailed introspection of the task tree:
nursery.child_tasks
,Task.child_nurseries
,nursery.parent_task
,Task.parent_nursery
trio.testing.wait_all_tasks_blocked()
now takes atiebreaker=
argument. The main use is to allowMockClock
’s auto-jump functionality to avoid interfering with direct use ofwait_all_tasks_blocked()
in the same test.MultiError.catch()
now correctly preserves__context__
, despite Python’s best attempts to stop us (#165)It is now possible to take weakrefs to
Lock
and many other classes (#331)Fix
sock.accept()
for IPv6 sockets (#164)PyCharm (and hopefully other IDEs) can now offer better completions for the
trio
andtrio.hazmat
modules (#314)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.