Release history¶
Trio 0.12.1 (2019-08-01)¶
Trio 0.12.0 (2019-07-31)¶
Features¶
If you have a
ReceiveStream
object, you can now useasync for data in stream: ...
instead of callingreceive_some
. Each iteration gives an arbitrary sized chunk of bytes. And the best part is, the loop automatically exits when you reach EOF, so you don’t have to check for it yourself anymore. Relatedly, you no longer need to pick a magic buffer size value before callingreceive_some
; you canawait stream.receive_some()
with no arguments, and the stream will automatically pick a reasonable size for you. (#959)Threading interfaces have been reworked:
run_sync_in_worker_thread
is nowtrio.to_thread.run_sync
, and instead ofBlockingTrioPortal
, usetrio.from_thread.run
andtrio.from_thread.run_sync
. What’s neat about this is that these cooperate, so if you’re in a thread created byto_thread.run_sync
, it remembers which Trio created it, and you can calltrio.from_thread.*
directly without having to pass around aBlockingTrioPortal
object everywhere. (#810)We cleaned up the distinction between the “abstract channel interface” and the “memory channel” concrete implementation.
trio.abc.SendChannel
andtrio.abc.ReceiveChannel
have been slimmed down,trio.MemorySendChannel
andtrio.MemoryReceiveChannel
are now public types that can be used in type hints, and there’s a newtrio.abc.Channel
interface for future bidirectional channels. (#719)Add
trio.run_process()
as a high-level helper for running a process and waiting for it to finish, like the standardsubprocess.run()
does. (#822)On Linux, when wrapping a bare file descriptor in a Trio socket object, Trio now auto-detects the correct
family
,type
, andprotocol
. This is useful, for example, when implementing systemd socket activation. (#251)Trio sockets have a new method
is_readable
that allows you to check whether a socket is readable. This is useful for HTTP/1.1 clients. (#760)We no longer use runtime code generation to dispatch core functions like
current_time
. Static analysis tools like mypy and pylint should now be able to recognize and analyze all of Trio’s top-level functions (though some class attributes are still dynamic… we’re working on it). (#805)Add
trio.hazmat.FdStream
for wrapping a Unix file descriptor as aStream
. (#829)Trio now gives a reasonable traceback and error message in most cases when its invariants surrounding cancel scope nesting have been violated. (One common source of such violations is an async generator that yields within a cancel scope.) The previous behavior was an inscrutable chain of TrioInternalErrors. (#882)
MultiError now defines its
exceptions
attribute in__init__()
to better support linters and code autocompletion. (#1066)Use
__slots__
in more places internally, which should make Trio slightly faster. (#984)
Bugfixes¶
Destructor methods (
__del__
) are now protected againstKeyboardInterrupt
. (#676)The
trio.Path
methodsglob()
andrglob()
now return iterables oftrio.Path
(notpathlib.Path
). (#917)Inspecting the
cancel_called
attribute of a not-yet-exited cancel scope whose deadline is in the past now always returnsTrue
, like you might expect. (Previously it would returnFalse
for not-yet-entered cancel scopes, and for active cancel scopes until the first checkpoint after their deadline expiry.) (#958)The
trio.Path
classmethods,home()
andcwd()
, are now async functions. Previously, a bug in the forwarding logic meantcwd()
was synchronous andhome()
didn’t work at all. (#960)An exception encapsulated within a
MultiError
doesn’t need to be hashable anymore.Note
This is only supported if you are running python >= 3.6.4. You can refer to this github PR for details. (#1005)
Improved Documentation¶
To help any user reading through Trio’s function implementations, start using public names (not _core) whenever possible. (#1017)
Deprecations and Removals¶
The
clear
method ontrio.Event
has been deprecated. (#637)BlockingTrioPortal
has been deprecated in favor of the newtrio.from_thread
. (#810)run_sync_in_worker_thread
is deprecated in favor oftrio.to_thread.run_sync
. (#810)current_default_worker_thread_limiter
is deprecated in favor oftrio.to_thread.current_default_thread_limiter
. (#810)Give up on trying to have different low-level waiting APIs on Unix and Windows. All platforms now have
trio.hazmat.wait_readable
,trio.hazmat.wait_writable
, andtrio.hazmat.notify_closing
. The old platform-specific synonymswait_socket_*
,notify_socket_closing
, andnotify_fd_closing
have been deprecated. (#878)It turns out that it’s better to treat subprocess spawning as an async operation. Therefore, direct construction of
Process
objects has been deprecated. Usetrio.open_process
instead. (#1109)
Miscellaneous internal changes¶
The plumbing of Trio’s cancellation system has been substantially overhauled to improve performance and ease future planned improvements. Notably, there is no longer any internal concept of a “cancel stack”, and checkpoints now take constant time regardless of the cancel scope nesting depth. (#58)
We’ve slightly relaxed our definition of which Trio operations act as checkpoints. A Trio async function that exits by throwing an exception is no longer guaranteed to execute a checkpoint; it might or might not. The rules are unchanged for async functions that don’t exit with an exception, async iterators, and async context managers.
trio.testing.assert_checkpoints()
has been updated to reflect the new behavior: if itswith
block exits with an exception, no assertion is made. (#474)Calling
str
on atrio.Cancelled
exception object returns “Cancelled” instead of an empty string. (#674)Change the default timeout in
trio.open_tcp_stream()
to 0.250 seconds, for consistency with RFC 8305. (#762)On win32 we no longer set SO_EXCLUSIVEADDRUSE when binding a socket in
trio.open_tcp_listeners
. (#928)Any attempt to inherit from
CancelScope
orNursery
now raisesTypeError
. (Trio has never been able to safely support subclassing here; this change just makes it more obvious.) Also exposed as public classes for type-checking, etc. (#1021)
Trio 0.11.0 (2019-02-09)¶
Features¶
Add support for “unbound cancel scopes”: you can now construct a
trio.CancelScope
without entering its context, e.g., so you can pass it to another task which will use it to wrap some work that you want to be able to cancel from afar. (#607)The test suite now passes with openssl v1.1.1. Unfortunately this required temporarily disabling TLS v1.3 during tests; see openssl bugs #7948 and #7967. We believe TLS v1.3 should work in most real use cases, but will be monitoring the situation. (#817)
Add
trio.Process.stdio
, which is aStapledStream
ofstdin
andstdout
if both of those are available, andNone
otherwise. This is intended to make it more ergonomic to speak a back-and-forth protocol with a subprocess. (#862)trio.Process
on POSIX systems no longer accepts the error-prone combination ofshell=False
with acommand
that’s a single string, orshell=True
with acommand
that’s a sequence of strings. These forms are accepted by the underlyingsubprocess.Popen
constructor but don’t do what most users expect. Also, added an explanation of quoting to the documentation. (#863)Added an internal mechanism for pytest-trio’s Hypothesis integration to make the task scheduler reproducible and avoid flaky tests. (#890)
SendChannel
,ReceiveChannel
,Listener
, andopen_memory_channel()
can now be referenced using a generic type parameter (the type of object sent over the channel or produced by the listener) using PEP 484 syntax:trio.abc.SendChannel[bytes]
,trio.abc.Listener[trio.SocketStream]
,trio.open_memory_channel[MyMessage](5)
, etc. The added type information does not change the runtime semantics, but permits better integration with external static type checkers. (#908)
Bugfixes¶
Fixed several bugs in the new Unix subprocess pipe support, where (a) operations on a closed pipe could accidentally affect another unrelated pipe due to internal file-descriptor reuse, (b) in very rare circumstances, two tasks calling
send_all
on the same pipe at the same time could end up with intermingled data instead of aBusyResourceError
. (#661)Stop
trio.open_tcp_listeners()
from crashing on systems that have disabled IPv6. (#853)Fixed support for multiple tasks calling
trio.Process.wait()
simultaneously; on kqueue platforms it would previously raise an exception. (#854)trio.Cancelled
exceptions now always propagate until they reach the outermost unshielded cancelled scope, even if more cancellations occur or shielding is changed between when theCancelled
is delivered and when it is caught. (#860)If you have a
SocketStream
that’s already been closed, thenawait socket_stream.send_all(b"")
will now correctly raiseClosedResourceError
. (#874)Simplified the Windows subprocess pipe
send_all
code, and in the process fixed a theoretical bug where closing a pipe at just the wrong time could produce errors or cause data to be redirected to the wrong pipe. (#883)
Deprecations and Removals¶
Deprecate
trio.open_cancel_scope
in favor oftrio.CancelScope
, which more clearly reflects that creating a cancel scope is just an ordinary object construction and does not need to be immediately paired with entering it. (#607)The submodules
trio.ssl
andtrio.subprocess
are now deprecated. Their nontrivial contents (Process
,SSLStream
, andSSLListener
) have been moved to the maintrio
namespace. For the numerous constants, exceptions, and other helpers that were previously reexported from the standardssl
andsubprocess
modules, you should now use those modules directly. (#852)Remove all the APIs deprecated in 0.9.0 or earlier (
trio.Queue
,trio.catch_signals()
,trio.BrokenStreamError
, andtrio.ResourceBusyError
), except fortrio.hazmat.UnboundedQueue
, which stays for now since it is used by the obscure hazmat functionsmonitor_completion_queue()
andmonitor_kevent()
. (#918)
Trio 0.10.0 (2019-01-07)¶
Features¶
Initial subprocess support. Add
trio.subprocess.Process
, an async wrapper around the stdlibsubprocess.Popen
class, which permits spawning subprocesses and communicating with them over standard Trio streams.trio.subprocess
also reexports all the stdlibsubprocess
exceptions and constants for convenience. (#4)You can now create an unbounded
CapacityLimiter
by initializing withmath.inf
(#618)New
trio.hazmat
features to allow cleanly switching live coroutine objects between Trio and other coroutine runners. Frankly, we’re not even sure this is a good idea, but we want to try it out in trio-asyncio, so here we are. For details see Handing off live coroutine objects between coroutine runners. (#649)
Bugfixes¶
Fixed a race condition on macOS, where Trio’s TCP listener would crash if an incoming TCP connection was closed before the listener had a chance to accept it. (#609)
trio.open_tcp_stream()
has been refactored to clean up unsuccessful connection attempts more reliably. (#809)
Deprecations and Removals¶
Remove the APIs deprecated in 0.5.0. (
ClosedStreamError
,ClosedListenerError
,Result
) (#812)
Miscellaneous internal changes¶
There are a number of methods on
trio.ssl.SSLStream
that report information about the negotiated TLS connection, likeselected_alpn_protocol
, and thus cannot succeed until after the handshake has been performed. Previously, we returned None from these methods, like the stdlibssl
module does, but this is confusing, because that can also be a valid return value. Now we raisetrio.ssl.NeedHandshakeError
instead. (#735)
Trio 0.9.0 (2018-10-12)¶
Features¶
New and improved APIs for inter-task communication:
trio.abc.SendChannel
,trio.abc.ReceiveChannel
, andtrio.open_memory_channel()
(which replacestrio.Queue
). This interface uses separate “sender” and “receiver” objects, for consistency with other communication interfaces likeStream
. Also, the two objects can now be closed individually, making it much easier to gracefully shut down a channel. Also, check out the niftyclone
API to make it easy to manage shutdown in multiple-producer/multiple-consumer scenarios. Also, the API has been written to allow for future channel implementations that send objects across process boundaries. Also, it supports unbounded buffering if you really need it. Also, help I can’t stop writing also. See Using channels to pass values between tasks for more details. (#497)
Deprecations and Removals¶
trio.Queue
andtrio.hazmat.UnboundedQueue
have been deprecated, in favor oftrio.open_memory_channel()
. (#497)
Trio 0.8.0 (2018-10-01)¶
Features¶
Trio’s default internal clock is now based on
time.perf_counter()
instead oftime.monotonic()
. This makes time-keeping more precise on Windows, and has no effect on other platforms. (#33)Reworked
trio
,trio.testing
, andtrio.socket
namespace construction, making them more understandable by static analysis tools. This should improve tab completion in editors, reduce false positives from pylint, and is a first step towards providing type hints. (#542)
Deprecations and Removals¶
ResourceBusyError
is now a deprecated alias for the newBusyResourceError
, andBrokenStreamError
is a deprecated alias for the newBrokenResourceError
. (#620)
Trio 0.7.0 (2018-09-03)¶
Features¶
The length of typical exception traces coming from Trio has been greatly reduced. This was done by eliminating many of the exception frames related to details of the implementation. For examples, see the blog post. (#56)
New and improved signal catching API:
open_signal_receiver()
. (#354)The low level
trio.hazmat.wait_socket_readable
,wait_socket_writable
, andnotify_socket_close
now work on bare socket descriptors, instead of requiring asocket.socket()
object. (#400)If you’re using
trio.hazmat.wait_task_rescheduled()
and other low-level routines to implement a new sleeping primitive, you can now use the newtrio.hazmat.Task.custom_sleep_data
attribute to pass arbitrary data between the sleeping task, abort function, and waking task. (#616)
Bugfixes¶
Prevent crashes when used with Sentry (raven-python). (#599)
The nursery context manager was rewritten to avoid use of
@asynccontextmanager
and@async_generator
. This reduces extraneous frames in exception traces and addresses bugs regardingStopIteration
andStopAsyncIteration
exceptions not propagating correctly. (#612)Updates the formatting of exception messages raised by
trio.open_tcp_stream()
to correctly handle a hostname passed in as bytes, by converting the hostname to a string. (#633)
Deprecations and Removals¶
trio.catch_signals
has been deprecated in favor ofopen_signal_receiver()
. The main differences are: it takes *-args now to specify the list of signals (soopen_signal_receiver(SIGINT)
instead ofcatch_signals({SIGINT})
), and, the async iterator now yields individual signals, instead of “batches” (#354)Remove all the APIs deprecated in 0.3.0 and 0.4.0. (#623)
Trio 0.6.0 (2018-08-13)¶
Features¶
Add
trio.hazmat.WaitForSingleObject()
async function to await Windows handles. (#233)The sniffio library can now detect when Trio is running. (#572)
Bugfixes¶
Make trio.socket._SocketType.connect always close the socket on cancellation (#247)
Fix a memory leak in
trio.CapacityLimiter
, that could occurr whenacquire
oracquire_on_behalf_of
was cancelled. (#548)Some version of macOS have a buggy
getaddrinfo
that was causing spurious test failures; we now detect those systems and skip the relevant test when found. (#580)Prevent crashes when used with Sentry (raven-python). (#599)
Trio 0.5.0 (2018-07-20)¶
Features¶
Suppose one task is blocked trying to use a resource – for example, reading from a socket – and while it’s doing this, another task closes the resource. Previously, this produced undefined behavior. Now, closing a resource causes pending operations on that resource to terminate immediately with a
ClosedResourceError
.ClosedStreamError
andClosedListenerError
are now aliases forClosedResourceError
, and deprecated. For this to work, Trio needs to know when a resource has been closed. To facilitate this, new functions have been added:trio.hazmat.notify_fd_close
andtrio.hazmat.notify_socket_close
. If you’re using Trio’s built-in wrappers likeSocketStream
ortrio.socket
, then you don’t need to worry about this, but if you’re using the low-level functions liketrio.hazmat.wait_readable()
, you should make sure to call these functions at appropriate times. (#36)Tasks created by
spawn_system_task()
now no longer inherit the creator’scontextvars
context, instead using one created atrun()
. (#289)Add support for
trio.Queue
withcapacity=0
. Queue’s implementation is also faster now. (#473)Switch to using standalone Outcome library for Result objects. (#494)
Trio 0.4.0 (2018-04-10)¶
Features¶
Add unix client socket support. (#401)
Add support for
contextvars
(see task-local storage), and addtrio.hazmat.RunVar
as a similar API for run-local variables. Deprecatetrio.TaskLocal
andtrio.hazmat.RunLocal
in favor of these new APIs. (#420)Add
trio.hazmat.current_root_task()
to get the root task. (#452)
Bugfixes¶
Fix KeyboardInterrupt handling when threading state has been modified by a 3rd-party library. (#461)
Deprecations and Removals¶
Attempting to explicitly raise
trio.Cancelled
will cause aRuntimeError
.cancel_scope.cancel()
should be used instead. (#342)
Miscellaneous internal changes¶
Simplify implementation of primitive traps like
wait_task_rescheduled()
(#395)
Trio 0.3.0 (2017-12-28)¶
Features¶
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 aasync 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 withasync 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
bind
andconnect
no longer require “pre-resolved” numeric addresses; you can now pass regular hostnames and Trio will implicitly resolve them for you. (#377)
Bugfixes¶
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
bind
method on Trio sockets is now async. Please update your calls or – better yet – switch to our shiny new high-level networking API, likeserve_tcp()
. (#241)The
resolve_local_address
andresolve_remote_address
methods 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.
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 implementation and checking that your custom stream implementation follows the stream 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
→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.