Skip to content

Latest commit

 

History

History
1576 lines (1194 loc) · 76.5 KB

history.rst

File metadata and controls

1576 lines (1194 loc) · 76.5 KB

Release history

.. currentmodule:: trio

Trio 0.25.1 (2024-05-16)

Bugfixes

  • Fix crash when importing trio in embedded Python on Windows, and other installs that remove docstrings. (#2987)

Trio 0.25.0 (2024-03-17)

Breaking changes

  • The :ref:`strict_exception_groups <strict_exception_groups>` parameter now defaults to True in trio.run and trio.lowlevel.start_guest_run. trio.open_nursery still defaults to the same value as was specified in trio.run/trio.lowlevel.start_guest_run, but if you didn't specify it there then all subsequent calls to trio.open_nursery will change. This is unfortunately very tricky to change with a deprecation period, as raising a DeprecationWarning whenever :ref:`strict_exception_groups <strict_exception_groups>` is not specified would raise a lot of unnecessary warnings.

    Notable side effects of changing code to run with strict_exception_groups==True

    • If an iterator raises StopAsyncIteration or StopIteration inside a nursery, then python will not recognize wrapped instances of those for stopping iteration.
    • trio.run_process is now documented that it can raise an ExceptionGroup. It previously could do this in very rare circumstances, but with :ref:`strict_exception_groups <strict_exception_groups>` set to True it will now do so whenever exceptions occur in deliver_cancel or with problems communicating with the subprocess.
      • Errors in opening the process is now done outside the internal nursery, so if code previously ran with strict_exception_groups=True there are cases now where an ExceptionGroup is no longer added.
    • trio.TrioInternalError .__cause__ might be wrapped in one or more ExceptionGroups <ExceptionGroup> (#2786)

Features

Bugfixes

  • The pthread functions are now correctly found on systems using vanilla versions of musl libc. (#2939)

Miscellaneous internal changes

  • use the regular readme for the PyPI long_description (#2866)

Trio 0.24.0 (2024-01-10)

Features

Deprecations and removals

  • MultiError has been fully removed, and all relevant trio functions now raise ExceptionGroups instead. This should not affect end users that have transitioned to using except* or catching ExceptionGroup/BaseExceptionGroup. (#2891)

Trio 0.23.2 (2023-12-14)

Features

Bugfixes

Miscellaneous internal changes

Trio 0.23.1 (2023-11-04)

Bugfixes

  • Don't crash on import in Anaconda interpreters. (#2855)

Trio 0.23.0 (2023-11-03)

Headline features

  • Add type hints. (#543)

Features

  • When exiting a nursery block, the parent task always waits for child tasks to exit. This wait cannot be cancelled. However, previously, if you tried to cancel it, it would inject a Cancelled exception, even though it wasn't cancelled. Most users probably never noticed either way, but injecting a Cancelled here is not really useful, and in some rare cases caused confusion or problems, so Trio no longer does that. (#1457)
  • If called from a thread spawned by trio.to_thread.run_sync, trio.from_thread.run and trio.from_thread.run_sync now reuse the task and cancellation status of the host task; this means that context variables and cancel scopes naturally propagate 'through' threads spawned by Trio. You can also use trio.from_thread.check_cancelled to efficiently check for cancellation without reentering the Trio thread. (#2392)
  • :func:`trio.lowlevel.start_guest_run` now does a bit more setup of the guest run before it returns to its caller, so that the caller can immediately make calls to :func:`trio.current_time`, :func:`trio.lowlevel.spawn_system_task`, :func:`trio.lowlevel.current_trio_token`, etc. (#2696)

Bugfixes

Deprecations and removals

  • To better reflect the underlying thread handling semantics, the keyword argument for trio.to_thread.run_sync that was previously called cancellable is now named abandon_on_cancel. It still does the same thing -- allow the thread to be abandoned if the call to trio.to_thread.run_sync is cancelled -- but since we now have other ways to propagate a cancellation without abandoning the thread, "cancellable" has become somewhat of a misnomer. The old cancellable name is now deprecated. (#2841)
  • Deprecated support for math.inf for the backlog argument in open_tcp_listeners, making its docstring correct in the fact that only TypeError is raised if invalid arguments are passed. (#2842)

Removals without deprecations

  • Drop support for Python3.7 and PyPy3.7/3.8. (#2668)
  • Removed special MultiError traceback handling for IPython. As of version 8.15 ExceptionGroup is handled natively. (#2702)

Miscellaneous internal changes

  • Trio now indicates its presence to sniffio using the sniffio.thread_local interface that is preferred since sniffio v1.3.0. This should be less likely than the previous approach to cause :func:`sniffio.current_async_library` to return incorrect results due to unintended inheritance of contextvars. (#2700)
  • On windows, if SIO_BASE_HANDLE failed and SIO_BSP_HANDLE_POLL didn't return a different socket, runtime error will now raise from the OSError that indicated the issue so that in the event it does happen it might help with debugging. (#2807)

Trio 0.22.2 (2023-07-13)

Bugfixes

  • Fix PermissionError when importing trio due to trying to access pthread. (#2688)

Trio 0.22.1 (2023-07-02)

Breaking changes

  • Timeout functions now raise ValueError if passed math.nan. This includes trio.sleep, trio.sleep_until, trio.move_on_at, trio.move_on_after, trio.fail_at and trio.fail_after. (#2493)

Features

  • Added support for naming threads created with trio.to_thread.run_sync, requires pthreads so is only available on POSIX platforms with glibc installed. (#1148)
  • trio.socket.socket now prints the address it tried to connect to upon failure. (#1810)

Bugfixes

  • Fixed a crash that can occur when running Trio within an embedded Python interpreter, by handling the TypeError that is raised when trying to (re-)install a C signal handler. (#2333)
  • Fix :func:`sniffio.current_async_library` when Trio tasks are spawned from a non-Trio context (such as when using trio-asyncio). Previously, a regular Trio task would inherit the non-Trio library name, and spawning a system task would cause the non-Trio caller to start thinking it was Trio. (#2462)
  • Issued a new release as in the git tag for 0.22.0, trio.__version__ is incorrectly set to 0.21.0+dev. (#2485)

Improved documentation

Trio 0.22.0 (2022-09-28)

Headline features

Features

Trio 0.21.0 (2022-06-07)

Features

Deprecations and Removals

  • Remove support for Python 3.6. (#2210)

Trio 0.20.0 (2022-02-21)

Features

  • You can now conveniently spawn a child process in a background task and interact it with on the fly using process = await nursery.start(run_process, ...). See run_process for more details. We recommend most users switch to this new API. Also note that:
    • trio.open_process has been deprecated in favor of trio.lowlevel.open_process,
    • The aclose method on Process has been deprecated along with async with process_obj. (#1104)
  • Now context variables set with contextvars are preserved when running functions in a worker thread with trio.to_thread.run_sync, or when running functions from the worker thread in the parent Trio thread with trio.from_thread.run, and trio.from_thread.run_sync. This is done by automatically copying the contextvars context. trio.lowlevel.spawn_system_task now also receives an optional context argument. (#2160)

Bugfixes

  • Trio now avoids creating cyclic garbage when a MultiError is generated and filtered, including invisibly within the cancellation system. This means errors raised through nurseries and cancel scopes should result in less GC latency. (#2063)
  • Trio now deterministically cleans up file descriptors that were opened before subprocess creation fails. Previously, they would remain open until the next run of the garbage collector. (#2193)
  • Add compatibility with OpenSSL 3.0 on newer Python and PyPy versions by working around SSLEOFError not being raised properly. (#2203)
  • Fix a bug that could cause Process.wait to hang on Linux systems using pidfds, if another task were to access Process.returncode after the process exited but before wait woke up (#2209)

Trio 0.19.0 (2021-06-15)

Features

  • Trio now supports Python 3.10. (#1921)
  • Use slots for :class:`~.lowlevel.Task` which should make them slightly smaller and faster. (#1927)
  • Make :class:`~.Event` more lightweight by using less objects (about 2 rather than 5, including a nested ParkingLot and attribute dicts) and simpler structures (set rather than OrderedDict). This may benefit applications that create a large number of event instances, such as with the "replace event object on every set()" idiom. (#1948)

Bugfixes

  • The event loop now holds on to references of coroutine frames for only the minimum necessary period of time. (#1864)
  • The :class:`~.lowlevel.TrioToken` class can now be used as a target of a weak reference. (#1924)

Trio 0.18.0 (2021-01-11)

Features

  • Add synchronous .close() methods and context manager (with x) support for .MemorySendChannel and .MemoryReceiveChannel. (#1797)

Bugfixes

  • Previously, on Windows, Trio programs using thousands of sockets at the same time could trigger extreme slowdowns in the Windows kernel. Now, Trio works around this issue, so you should be able to use as many sockets as you want. (#1280)
  • :func:`trio.from_thread.run` no longer crashes the Trio run if it is executed after the system nursery has been closed but before the run has finished. Calls made at this time will now raise trio.RunFinishedError. This fixes a regression introduced in Trio 0.17.0. The window in question is only one scheduler tick long in most cases, but may be longer if async generators need to be cleaned up. (#1738)
  • Fix a crash in pypy-3.7 (#1765)
  • Trio now avoids creating cyclic garbage as often. This should have a minimal impact on most programs, but can slightly reduce how often the cycle collector GC runs on CPython, which can reduce latency spikes. (#1770)

Deprecations and removals

  • Remove deprecated max_refill_bytes from :class:`SSLStream`. (#959)
  • Remove the deprecated tiebreaker argument to trio.testing.wait_all_tasks_blocked. (#1558)
  • Remove the deprecated trio.hazmat module. (#1722)
  • Stop allowing subclassing public classes. This behavior was deprecated in 0.15.0. (#1726)

Trio 0.17.0 (2020-09-15)

Headline features

  • Trio now supports automatic :ref:`async generator finalization <async-generators>`, so more async generators will work even if you don't wrap them in async with async_generator.aclosing(): blocks. Please see the documentation for important caveats; in particular, yielding within a nursery or cancel scope remains unsupported. (#265)

Features

  • trio.open_tcp_stream has a new local_address= keyword argument that can be used on machines with multiple IP addresses to control which IP is used for the outgoing connection. (#275)
  • If you pass a raw IP address into sendto, it no longer spends any time trying to resolve the hostname. If you're using UDP, this should substantially reduce your per-packet overhead. (#1595)
  • trio.lowlevel.checkpoint is now much faster. (#1613)
  • We switched to a new, lower-overhead data structure to track upcoming timeouts, which should make your programs faster. (#1629)

Bugfixes

  • On macOS and BSDs, explicitly close our wakeup socketpair when we're done with it. (#1621)
  • Trio can now be imported when sys.excepthook is a functools.partial instance, which might occur in a pytest-qt test function. (#1630)
  • The thread cache didn't release its reference to the previous job. (#1638)
  • On Windows, Trio now works around the buggy behavior of certain Layered Service Providers (system components that can intercept network activity) that are built on top of a commercially available library called Komodia Redirector. This benefits users of products such as Astrill VPN and Qustodio parental controls. Previously, Trio would crash on startup when run on a system where such a product was installed. (#1659)

Deprecations and removals

  • Remove wait_socket_*, notify_socket_closing, notify_fd_closing, run_sync_in_worker_thread and current_default_worker_thread_limiter. They were deprecated in 0.12.0. (#1596)

Miscellaneous internal changes

  • When using :ref:`instruments <instrumentation>`, you now only "pay for what you use": if there are no instruments installed that override a particular hook such as :meth:`~trio.abc.Instrument.before_task_step`, then Trio doesn't waste any effort on checking its instruments when the event corresponding to that hook occurs. Previously, installing any instrument would incur all the instrumentation overhead, even for hooks no one was interested in. (#1340)

Trio 0.16.0 (2020-06-10)

Headline features

  • If you want to use Trio, but are stuck with some other event loop like Qt or PyGame, then good news: now you can have both. For details, see: :ref:`guest-mode`. (#399)

Features

  • To speed up trio.to_thread.run_sync, Trio now caches and reuses worker threads.

    And in case you have some exotic use case where you need to spawn threads manually, but want to take advantage of Trio's cache, you can do that using the new trio.lowlevel.start_thread_soon. (#6)

  • Tasks spawned with nursery.start() <trio.Nursery.start> aren't treated as direct children of their nursery until they call task_status.started(). This is visible through the task tree introspection attributes such as Task.parent_nursery <trio.lowlevel.Task.parent_nursery>. Sometimes, though, you want to know where the task is going to wind up, even if it hasn't finished initializing yet. To support this, we added a new attribute Task.eventual_parent_nursery <trio.lowlevel.Task.eventual_parent_nursery>. For a task spawned with :meth:`~trio.Nursery.start` that hasn't yet called started(), this is the nursery that the task was nominally started in, where it will be running once it finishes starting up. In all other cases, it is None. (#1558)

Bugfixes

  • Added a helpful error message if an async function is passed to trio.to_thread.run_sync. (#1573)

Deprecations and removals

  • Remove BlockingTrioPortal: it was deprecated in 0.12.0. (#1574)
  • The tiebreaker argument to trio.testing.wait_all_tasks_blocked has been deprecated. This is a highly obscure feature that was probably never used by anyone except trio.testing.MockClock, and ~trio.testing.MockClock doesn't need it anymore. (#1587)
  • Remove the deprecated trio.ssl and trio.subprocess modules. (#1594)

Miscellaneous internal changes

  • We refactored trio.testing.MockClock so that it no longer needs to run an internal task to manage autojumping. This should be mostly invisible to users, but there is one semantic change: the interaction between trio.testing.wait_all_tasks_blocked and the autojump clock was fixed. Now, the autojump will always wait until after all ~trio.testing.wait_all_tasks_blocked calls have finished before firing, instead of it depending on which threshold values you passed. (#1587)

Trio 0.15.1 (2020-05-22)

Bugfixes

  • Fix documentation build. (This must be a new release tag to get readthedocs "stable" to include the changes from 0.15.0.)
  • Added a helpful error message if an async function is passed to trio.from_thread.run_sync or a sync function to trio.from_thread.run. (#1244)

Trio 0.15.0 (2020-05-19)

Features

  • Previously, when trio.run_process was cancelled, it always killed the subprocess immediately. Now, on Unix, it first gives the process a chance to clean up by sending SIGTERM, and only escalates to SIGKILL if the process is still running after 5 seconds. But if you prefer the old behavior, or want to adjust the timeout, then don't worry: you can now pass a custom deliver_cancel= argument to define your own process killing policy. (#1104)
  • It turns out that creating a subprocess can block the parent process for a surprisingly long time. So trio.open_process now uses a worker thread to avoid blocking the event loop. (#1109)
  • We've added FreeBSD to the list of platforms we support and test on. (#1118)
  • On Linux kernels v5.3 or newer, trio.Process.wait now uses the pidfd API to track child processes. This shouldn't have any user-visible change, but it makes working with subprocesses faster and use less memory. (#1241)
  • The trio.Process.returncode attribute is now automatically updated as needed, instead of only when you call ~trio.Process.poll or ~trio.Process.wait. Also, repr(process_object) now always contains up-to-date information about the process status. (#1315)

Bugfixes

  • On Ubuntu systems, the system Python includes a custom unhandled-exception hook to perform crash reporting. Unfortunately, Trio wants to use the same hook to print nice MultiError tracebacks, causing a conflict. Previously, Trio would detect the conflict, print a warning, and you just wouldn't get nice MultiError tracebacks. Now, Trio has gotten clever enough to integrate its hook with Ubuntu's, so the two systems should Just Work together. (#1065)
  • Fixed an over-strict test that caused failures on Alpine Linux. Started testing against Alpine in CI. (#1499)
  • Calling open_signal_receiver with no arguments used to succeed without listening for any signals. This was confusing, so now it raises TypeError instead. (#1526)

Deprecations and Removals

  • Remove support for Python 3.5. (#75)

  • It turns out that everyone got confused by the name trio.hazmat. So that name has been deprecated, and the new name is :mod:`trio.lowlevel`. (#476)

  • Most of the public classes that Trio exports – like trio.Lock, trio.SocketStream, and so on – weren't designed with subclassing in mind. And we've noticed that some users were trying to subclass them anyway, and ending up with fragile code that we're likely to accidentally break in the future, or else be stuck unable to make changes for fear of breaking subclasses.

    There are also some classes that were explicitly designed to be subclassed, like the ones in trio.abc. Subclassing these is still supported. However, for all other classes, attempts to subclass will now raise a deprecation warning, and in the future will raise an error.

    If this causes problems for you, feel free to drop by our chat room or file a bug, to discuss alternatives or make a case for why some particular class should be designed to support subclassing. (#1044)

  • If you want to create a trio.Process object, you now have to call trio.open_process; calling trio.Process() directly was deprecated in v0.12.0 and has now been removed. (#1109)

  • Remove clear method on trio.Event: it was deprecated in 0.12.0. (#1498)

Trio 0.14.0 (2020-04-27)

Features

  • If you're using Trio's low-level interfaces like trio.hazmat.wait_readable <trio.lowlevel.wait_readable> or similar, and then you close a socket or file descriptor, you're supposed to call trio.hazmat.notify_closing <trio.lowlevel.notify_closing> first so Trio can clean up properly. But what if you forget? In the past, Trio would tend to either deadlock or explode spectacularly. Now, it's much more robust to this situation, and should generally survive. (But note that "survive" is not the same as "give you the results you were expecting", so you should still call ~trio.lowlevel.notify_closing when appropriate. This is about harm reduction and making it easier to debug this kind of mistake, not something you should rely on.)

    If you're using higher-level interfaces outside of the trio.hazmat <trio.lowlevel> module, then you don't need to worry about any of this; those interfaces already take care of calling ~trio.lowlevel.notify_closing for you. (#1272)

Bugfixes

  • A bug related to the following methods has been introduced in version 0.12.0:

    • trio.Path.iterdir
    • trio.Path.glob
    • trio.Path.rglob

    The iteration of the blocking generators produced by pathlib was performed in the trio thread. With this fix, the previous behavior is restored: the blocking generators are converted into lists in a thread dedicated to blocking IO calls. (#1308)

Deprecations and Removals

  • Deprecate Python 3.5 (#1408)
  • Remove trio.open_cancel_scope which was deprecated in 0.11.0. (#1458)

Trio 0.13.0 (2019-11-02)

Features

  • On Windows, the IOCP subsystem is generally the best way to implement async I/O operations – but it's historically been weak at providing select-style readiness notifications, like trio.hazmat.wait_readable <trio.lowlevel.wait_readable> and ~trio.lowlevel.wait_writable. We aren't willing to give those up, so previously Trio's Windows backend used a hybrid of select + IOCP. This was complex, slow, and had limited scalability.

    Fortunately, we found a way to implement wait_* with IOCP, so Trio's Windows backend has been completely rewritten, and now uses IOCP exclusively. As a user, the only difference you should notice is that Trio should now be faster on Windows, and can handle many more sockets. This also simplified the code internally, which should allow for more improvements in the future.

    However, this is somewhat experimental, so if you use Windows then please keep an eye out and let us know if you run into any problems! (#52)

  • Use slots for memory channel state and statistics which should make memory channels slightly smaller and faster. (#1195)

Bugfixes

  • OpenSSL has a bug in its handling of TLS 1.3 session tickets that can cause deadlocks or data loss in some rare edge cases. These edge cases most frequently happen during tests. (Upstream bug reports: openssl/openssl#7948, openssl/openssl#7967.) trio.SSLStream now works around this issue, so you don't have to worry about it. (#819)
  • Trio now uses signal.set_wakeup_fd on all platforms. This is mostly an internal refactoring with no user-visible effect, but in theory it should fix a few extremely-rare race conditions on Unix that could have caused signal delivery to be delayed. (#109)
  • Trio no longer crashes when an async function is implemented in C or Cython and then passed directly to trio.run or nursery.start_soon. (#550, #1191)
  • When a Trio task makes improper use of a non-Trio async library, Trio now causes an exception to be raised within the task at the point of the error, rather than abandoning the task and raising an error in its parent. This improves debuggability and resolves the TrioInternalError that would sometimes result from the old strategy. (#552)
  • In 0.12.0 we deprecated trio.run_sync_in_worker_thread in favor of trio.to_thread.run_sync. But, the deprecation message listed the wrong name for the replacement. The message now gives the correct name. (#810)
  • Fix regression introduced with cancellation changes in 0.12.0, where a trio.CancelScope which isn't cancelled could catch a propagating trio.Cancelled exception if shielding were changed while the cancellation was propagating. (#1175)
  • Fix a crash that could happen when using MockClock with autojump enabled and a non-zero rate. (#1190)
  • If you nest >1000 cancel scopes within each other, Trio now handles that gracefully instead of crashing with a RecursionError. (#1235)
  • Fixed the hash behavior of trio.Path to match pathlib.Path. Previously trio.Path's hash was inherited from object instead of from pathlib.PurePath. Thus, hashing two trio.Path's or a trio.Path and a pathlib.Path with the same underlying path would yield different results. (#1259)

Trio 0.12.1 (2019-08-01)

Bugfixes

  • In v0.12.0, we accidentally moved BlockingTrioPortal from trio to trio.hazmat. It's now been restored to its proper position. (It's still deprecated though, and will issue a warning if you use it.) (#1167)

Trio 0.12.0 (2019-07-31)

Features

  • If you have a ~trio.abc.ReceiveStream object, you can now use async for data in stream: ... instead of calling ~trio.abc.ReceiveStream.receive_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 calling ~trio.abc.ReceiveStream.receive_some; you can await 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 now trio.to_thread.run_sync, and instead of BlockingTrioPortal, use trio.from_thread.run and trio.from_thread.run_sync. What's neat about this is that these cooperate, so if you're in a thread created by to_thread.run_sync, it remembers which Trio created it, and you can call trio.from_thread.* directly without having to pass around a BlockingTrioPortal object everywhere. (#810)
  • We cleaned up the distinction between the "abstract channel interface" and the "memory channel" concrete implementation. trio.abc.SendChannel and trio.abc.ReceiveChannel have been slimmed down, trio.MemorySendChannel and trio.MemoryReceiveChannel are now public types that can be used in type hints, and there's a new trio.abc.Channel interface for future bidirectional channels. (#719)
  • Add :func:`trio.run_process` as a high-level helper for running a process and waiting for it to finish, like the standard :func:`subprocess.run` does. (#822)
  • On Linux, when wrapping a bare file descriptor in a Trio socket object, Trio now auto-detects the correct family, type, and protocol. This is useful, for example, when implementing systemd socket activation. (#251)
  • Trio sockets have a new method ~trio.socket.SocketType.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 <trio.lowlevel.FdStream> for wrapping a Unix file descriptor as a ~trio.abc.Stream. (#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

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 on trio.Event has been deprecated. (#637)
  • BlockingTrioPortal has been deprecated in favor of the new trio.from_thread. (#810)
  • run_sync_in_worker_thread is deprecated in favor of trio.to_thread.run_sync. (#810)
  • current_default_worker_thread_limiter is deprecated in favor of trio.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.lowlevel.wait_readable>, trio.hazmat.wait_writable <trio.lowlevel.wait_writable>, and trio.hazmat.notify_closing <trio.lowlevel.notify_closing>. The old platform-specific synonyms wait_socket_*, notify_socket_closing, and notify_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. Use trio.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 :ref:`checkpoints <checkpoint-rule>`. 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. :func:`trio.testing.assert_checkpoints` has been updated to reflect the new behavior: if its with block exits with an exception, no assertion is made. (#474)
  • Calling str on a :exc:`trio.Cancelled` exception object returns "Cancelled" instead of an empty string. (#674)
  • Change the default timeout in :func:`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 :exc:`trio.open_tcp_listeners`. (#928)
  • Any attempt to inherit from CancelScope or Nursery now raises TypeError. (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

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 a :exc:`BusyResourceError`. (#661)
  • Stop :func:`trio.open_tcp_listeners` from crashing on systems that have disabled IPv6. (#853)
  • Fixed support for multiple tasks calling :meth:`trio.Process.wait` simultaneously; on kqueue platforms it would previously raise an exception. (#854)
  • :exc:`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 the :exc:`~trio.Cancelled` is delivered and when it is caught. (#860)
  • If you have a :class:`SocketStream` that's already been closed, then await socket_stream.send_all(b"") will now correctly raise :exc:`ClosedResourceError`. (#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 of :class:`trio.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 and trio.subprocess are now deprecated. Their nontrivial contents (:class:`~trio.Process`, :class:`~trio.SSLStream`, and :class:`~trio.SSLListener`) have been moved to the main :mod:`trio` namespace. For the numerous constants, exceptions, and other helpers that were previously reexported from the standard :mod:`ssl` and :mod:`subprocess` 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, and trio.ResourceBusyError), except for trio.hazmat.UnboundedQueue, which stays for now since it is used by the obscure lowlevel functions monitor_completion_queue() and monitor_kevent(). (#918)

Miscellaneous internal changes

  • Entering a cancel scope whose deadline is in the past now immediately cancels it, so :exc:`~trio.Cancelled` will be raised by the first checkpoint in the cancel scope rather than the second one. This also affects constructs like with trio.move_on_after(0):. (#320)

Trio 0.10.0 (2019-01-07)

Features

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)
  • :func:`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

Trio 0.9.0 (2018-10-12)

Features

  • New and improved APIs for inter-task communication: :class:`trio.abc.SendChannel`, :class:`trio.abc.ReceiveChannel`, and :func:`trio.open_memory_channel` (which replaces trio.Queue). This interface uses separate "sender" and "receiver" objects, for consistency with other communication interfaces like :class:`~trio.abc.Stream`. Also, the two objects can now be closed individually, making it much easier to gracefully shut down a channel. Also, check out the nifty clone 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 :ref:`channels` for more details. (#497)

Deprecations and Removals

Trio 0.8.0 (2018-10-01)

Features

Deprecations and Removals

Trio 0.7.0 (2018-09-03)

Features

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 regarding StopIteration and StopAsyncIteration exceptions not propagating correctly. (#612)
  • Updates the formatting of exception messages raised by :func:`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 of :func:`open_signal_receiver`. The main differences are: it takes *-args now to specify the list of signals (so open_signal_receiver(SIGINT) instead of catch_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

Bugfixes

  • Make trio.socket._SocketType.connect always close the socket on cancellation (#247)
  • Fix a memory leak in :class:`trio.CapacityLimiter`, that could occur when acquire or acquire_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 :exc:`ClosedResourceError`. ClosedStreamError and ClosedListenerError are now aliases for :exc:`ClosedResourceError`, 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 and trio.hazmat.notify_socket_close. If you're using Trio's built-in wrappers like :class:`~trio.SocketStream` or :mod:`trio.socket`, then you don't need to worry about this, but if you're using the low-level functions like :func:`trio.hazmat.wait_readable <trio.lowlevel.wait_readable>`, you should make sure to call these functions at appropriate times. (#36)
  • Tasks created by :func:`~trio.lowlevel.spawn_system_task` now no longer inherit the creator's :mod:`contextvars` context, instead using one created at :func:`~trio.run`. (#289)
  • Add support for trio.Queue with capacity=0. Queue's implementation is also faster now. (#473)
  • Switch to using standalone Outcome library for Result objects. (#494)

Deprecations and Removals

  • trio.hazmat.Result, trio.hazmat.Value and trio.hazmat.Error have been replaced by the equivalent classes in the Outcome library.

Trio 0.4.0 (2018-04-10)

Features

Bugfixes

  • Fix KeyboardInterrupt handling when threading state has been modified by a 3rd-party library. (#461)

Deprecations and Removals

Miscellaneous internal changes

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 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 bind and connect 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, like :func:`serve_tcp`. (#241)
  • The resolve_local_address and resolve_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

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 like :func:`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):

  • :mod:`trio.socket` no longer attempts to normalize or modernize socket options across different platforms. The high-level networking API now handles that, freeing :mod:`trio.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 an :class:`~trio.SSLStream` wrapped around a :class:`~trio.SocketStream` 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 a sendall is cancelled.
  • The :func:`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 :mod:`trio.socket` functions getservbyport, getservbyname, and getfqdn have been removed, because they were obscure, buggy, and obsolete. Use :func:`~trio.socket.getaddrinfo` 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):

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 :ref:`robust mechanism for applying capacity limits to the number of concurrent threads <worker-thread-limiting>` (#10, #57, #156)

  • New support for tests to cleanly hook hostname lookup and socket operations: see :ref:`virtual-network-hooks`. 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 was isinstance checks, and those still work (#170)

  • New class :class:`StrictFIFOLock`

  • New exception ResourceBusyError

  • The :class:`trio.hazmat.ParkingLot <trio.lowlevel.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 be trio.run(some_func)).

  • :mod:`trio.socket` now handles non-ascii domain names using the modern IDNA 2008 standard instead of the obsolete IDNA 2003 standard (#11)

  • When an :class:`~trio.abc.Instrument` raises an unexpected error, we now route it through the :mod:`logging` 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 :func:`signal.set_wakeup_fd` and should be more reliable (#42)

  • :func:`trio.run` takes a new keyword argument restrict_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

  • :func:`trio.testing.wait_all_tasks_blocked` now takes a tiebreaker= argument. The main use is to allow :class:`~trio.testing.MockClock`'s auto-jump functionality to avoid interfering with direct use of :func:`~trio.testing.wait_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 :class:`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 :mod:`trio` and :mod:`trio.hazmat <trio.lowlevel>` 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.