anyio

Developer Tools

High-level concurrency and networking framework on top of asyncio or Trio

Latest 4.14.2 · by agronholmWebsiteagronholm/anyio

Release activity

Release activity — 8 releases across 8 days in the last year. Each cell is one day; darker means more releases that day. Older weeks are hidden at this screen width.
MayJunJulAug
SundayNo releases on Apr 19, 2026No releases on Apr 26, 2026No releases on May 3, 2026No releases on May 10, 2026No releases on May 17, 2026No releases on May 24, 2026No releases on May 31, 2026No releases on Jun 7, 2026No releases on Jun 14, 2026No releases on Jun 21, 2026No releases on Jun 28, 2026No releases on Jul 5, 20261 release on Jul 12, 2026No releases on Jul 19, 2026No releases on Jul 26, 2026No releases on Aug 2, 2026
MondayNo releases on Apr 20, 2026No releases on Apr 27, 2026No releases on May 4, 2026No releases on May 11, 2026No releases on May 18, 2026No releases on May 25, 2026No releases on Jun 1, 2026No releases on Jun 8, 20261 release on Jun 15, 2026No releases on Jun 22, 2026No releases on Jun 29, 2026No releases on Jul 6, 2026No releases on Jul 13, 2026No releases on Jul 20, 2026No releases on Jul 27, 2026No releases on Aug 3, 2026
TuesdayNo releases on Apr 21, 2026No releases on Apr 28, 2026No releases on May 5, 2026No releases on May 12, 2026No releases on May 19, 2026No releases on May 26, 2026No releases on Jun 2, 2026No releases on Jun 9, 2026No releases on Jun 16, 2026No releases on Jun 23, 2026No releases on Jun 30, 2026No releases on Jul 7, 2026No releases on Jul 14, 2026No releases on Jul 21, 2026No releases on Jul 28, 2026No releases on Aug 4, 2026
WednesdayNo releases on Apr 22, 2026No releases on Apr 29, 2026No releases on May 6, 2026No releases on May 13, 2026No releases on May 20, 2026No releases on May 27, 2026No releases on Jun 3, 2026No releases on Jun 10, 2026No releases on Jun 17, 20261 release on Jun 24, 2026No releases on Jul 1, 2026No releases on Jul 8, 2026No releases on Jul 15, 2026No releases on Jul 22, 2026No releases on Jul 29, 2026No releases on Aug 5, 2026
ThursdayNo releases on Apr 23, 2026No releases on Apr 30, 2026No releases on May 7, 2026No releases on May 14, 2026No releases on May 21, 2026No releases on May 28, 2026No releases on Jun 4, 2026No releases on Jun 11, 2026No releases on Jun 18, 2026No releases on Jun 25, 2026No releases on Jul 2, 2026No releases on Jul 9, 2026No releases on Jul 16, 2026No releases on Jul 23, 2026No releases on Jul 30, 2026
FridayNo releases on Apr 24, 2026No releases on May 1, 2026No releases on May 8, 2026No releases on May 15, 2026No releases on May 22, 2026No releases on May 29, 2026No releases on Jun 5, 2026No releases on Jun 12, 2026No releases on Jun 19, 2026No releases on Jun 26, 2026No releases on Jul 3, 2026No releases on Jul 10, 2026No releases on Jul 17, 2026No releases on Jul 24, 2026No releases on Jul 31, 2026
SaturdayNo releases on Apr 25, 2026No releases on May 2, 2026No releases on May 9, 2026No releases on May 16, 2026No releases on May 23, 2026No releases on May 30, 2026No releases on Jun 6, 2026No releases on Jun 13, 2026No releases on Jun 20, 2026No releases on Jun 27, 2026No releases on Jul 4, 2026No releases on Jul 11, 2026No releases on Jul 18, 2026No releases on Jul 25, 2026No releases on Aug 1, 2026

8 releases in the last year

Changelog

4.14.2

Changed 1
  • Changed ByteReceiveStream.receive() implementations to raise a ValueError when max_bytes is not a positive integer
Fixed 7
  • Fixed CapacityLimiter.total_tokens rejecting float("inf") when the limiter was instantiated outside of an event loop
  • Fixed to_process.run_sync() deadlocking when the worker function writes enough data to sys.stderr to fill the pipe buffer
  • Fixed TLSStream.wrap() matching an internationalized host name against the peer certificate using IDNA 2003 instead of IDNA 2008
  • Fixed anyio.open_process() and run_process() ignoring the extra_groups argument
  • Fixed CapacityLimiter.acquire_nowait() and CapacityLimiter.acquire_nowait_on_behalf_of() raising trio.WouldBlock instead of anyio.WouldBlock on the trio backend
  • Fixed CapacityLimiter on the asyncio backend over-granting tokens when a non-blocking acquire was made between a token being released and the notified waiter resuming
  • Fixed unnecessary CPU spin when delivering cancellation from CancelScope on asyncio under certain conditions
  • Changed ByteReceiveStream.receive() implementations to raise a ValueError when max_bytes is not a positive integer (#1191)
  • Fixed CapacityLimiter.total_tokens rejecting float("inf") when the limiter was instantiated outside of an event loop. The adapter setter checked for infinity by identity (value is math.inf), so only the exact math.inf singleton was accepted, while every backend setter (using math.isinf()) accepts any positive infinity (#1189; PR by @greymoth-jp).
  • Fixed to_process.run_sync() deadlocking when the worker function writes enough data to sys.stderr to fill the (undrained) pipe buffer. The worker process now redirects sys.stderr to os.devnull as well, matching the documented behavior
  • Fixed TLSStream.wrap() matching an internationalized (unicode) host name against the peer certificate using IDNA 2003 (via the standard library) instead of IDNA 2008, which could cause the host name to be matched against the wrong certificate (#1208)
  • Fixed anyio.open_process() (and run_process()) ignoring the extra_groups argument, as it mistakenly passed the value of the group argument instead (#1209)
  • Fixed CapacityLimiter.acquire_nowait() and CapacityLimiter.acquire_nowait_on_behalf_of() raising trio.WouldBlock instead of anyio.WouldBlock on the trio backend when there are no tokens available (#1218)
  • Fixed CapacityLimiter on the asyncio backend over-granting tokens (borrowed_tokens exceeding total_tokens and available_tokens going negative) when a non-blocking acquire was made in the window between a token being released and the notified waiter resuming. The freed token is now reserved for the woken waiter right away, so the non-blocking acquire correctly raises WouldBlock (#1170; PR by @gaoflow)
  • Fixed unnecessary CPU spin when delivering cancellation from CancelScope on asyncio under certain conditions, including improper cancel scope nesting (#1111)

4.14.1

Fixed 2
  • Teardown of higher-scoped async fixtures failing on asyncio with RuntimeError when an async test raises an outcome exception such as pytest.skip(), pytest.xfail(), or pytest.fail()
  • CapacityLimiter.total_tokens rejecting a value of 0 when the limiter was instantiated outside of an event loop, contradicting the documented behavior
  • Fixed teardown of higher-scoped async fixtures failing on asyncio with RuntimeError: Attempted to exit cancel scope in a different task than it was entered in when an async test raise an outcome exception (e.g., pytest.skip(), pytest.xfail(), or pytest.fail()) (#1179; PR by @EmmanuelNiyonshuti)
  • Fixed CapacityLimiter.total_tokens rejecting a value of 0 when the limiter was instantiated outside of an event loop, contradicting the documented behavior of allowing 0 total tokens (#1183; PR by @nyxst4ck)

4.14.0

Added 7
  • Support for Python 3.15
  • Asynchronous implementation of the itertools module
  • Added the local_port parameter to connect_tcp() to allow binding to a specific local port before connecting
  • Support for custom capacity limiters in async path and file I/O functions and classes
  • Added the create_task() task group method for easier asyncio migration
  • Added an option for TaskGroup.start() to return a TaskHandle containing the start value in the start_value property
  • Added the cancel() convenience method to TaskGroup as a shortcut for cancelling the task group's cancel scope
Changed 7
  • TaskGroup.start_soon() now returns a TaskHandle
  • Improved error message when a known backend is not installed to suggest the install command
  • Improved anyio.Path to preserve subclass types by returning Self in methods that return path objects
  • Changed the parameter type annotation in anyio.Path.write_bytes() to accept any ReadableBuffer, allowing bytearray and memoryview
  • Changed type annotations in TaskGroup.start_soon(), TaskGroup.start(), and anyio.from_thread.run() to only accept callables returning coroutine-like objects instead of arbitrary awaitables
  • Changed anyio.run to support callables returning arbitrary awaitables at runtime on all backends
  • Added __slots__ to CancelScope, CapacityLimiter, Condition, Event, Lock, ResourceGuard, and Semaphore
Fixed 6
  • Fixed cancellation exception escaping a cancel scope when triggered via check_cancelled() in a worker thread
  • Fixed TaskGroup raising AttributeError instead of a clear error when entered more than once
  • Fixed lost type information when passing arguments to lru_cache
  • Fixed test resumption after KeyboardInterrupt in async generator fixtures on the asyncio backend
  • Fixed import of __main__ in to_process workers when entrypoint script doesn't end in .py
  • Fixed SocketListener.from_socket() returning a TCP listener for AF_UNIX listening sockets
  • Added support for Python 3.15

  • Added an asynchronous implementation of the itertools module (#998; PR by @11kkw)

  • Added the local_port parameter to connect_tcp() to allow binding to a specific local port before connecting (#1067; PR by @nullwiz)

  • Added support for custom capacity limiters in async path and file I/O functions and classes

  • Added the create_task() task group method for easier asyncio migration (returns a TaskHandle) (#1098)

  • Changed TaskGroup.start_soon() to return a TaskHandle

  • Added an option for TaskGroup.start() to return a TaskHandle (which then contains the start value in the start_value property)

  • Added the cancel() convenience method to TaskGroup as a shortcut for cancelling the task group's cancel scope

  • Improved the error message when a known backend is not installed to suggest the install command (#1115; PR by @EmmanuelNiyonshuti)

  • Improved anyio.Path to preserve subclass types by returning Self in methods that return path objects (#1130; PR by @EmmanuelNiyonshuti)

  • Changed the parameter type annotation in anyio.Path.write_bytes() to accept any ReadableBuffer, thus allowing it to accept bytearray and memoryview to match pathlib.Path.write_bytes() (#1135; PR by @SAY-5)

  • Changed several type annotations to only accept callables returning coroutine-like objects instead of arbitrary awaitables:

    • TaskGroup.start_soon()
    • TaskGroup.start()
    • anyio.from_thread.run()

    This reverts an earlier change from v3.7.0 which was made in error. (#1153)

  • Changed anyio.run to support callables returning arbitrary awaitables at runtime on all backends. Previously, this only worked on asyncio (#1171; PR by @gschaffner)

  • Changed several classes (and their subclasses) to have __slots__ (with __weakref__):

    • anyio.CancelScope
    • anyio.CapacityLimiter
    • anyio.Condition
    • anyio.Event
    • anyio.Lock
    • anyio.ResourceGuard
    • anyio.Semaphore
  • Fixed cancellation exception escaping a cancel scope when triggered via check_cancelled() in a worker thread (#1113)

  • Fixed TaskGroup raising AttributeError instead of a clear error when entered more than once (#1109; PR by @bahtya)

  • Fixed lost type information when passing arguments to lru_cache (#1104; PR by @Graeme22)

  • Fixed test resumption after KeyboardInterrupt in async generator fixtures on the asyncio backend (#1060; PR by @EmmanuelNiyonshuti)

  • Fixed import of __main__ in to_process workers when entrypoint script doesn't end in .py, such as when using console_script entrypoints. (#1027; PR by @tapetersen)

  • Fixed SocketListener.from_socket() returning a TCP listener for AF_UNIX listening sockets, causing accept() to fail with ENOTSUP (#1132; PR by @kudato)

  • Fixed UDPSocket.aclose() and ConnectedUDPSocket.aclose() on asyncio returning before the underlying socket FD was actually released (#1147; PR by @matias-arrelid)

  • Fixed trio backend test runner hanging indefinitely instead of raising an error when dynamically accessing an async fixture via request.getfixturevalue (#1148; PR by @EmmanuelNiyonshuti)

  • Fixed cancelling tasks started through a BlockingPortal after the portal has been stopped (#1013; PR by @puneetdixit200)

  • Fixed backend_options being ignored when running the Trio backend via anyio.run(); the options are now passed as keyword arguments to trio.run() again, as documented (a regression from AnyIO 3) (#1161; PR by @Zac-HD)

  • Fixed asyncio Lock and Semaphore deadlocks caused by cancelled waiters left queued during release (#1145; PR by @rasmusfaber, @x42005e1f and @agronholm)

4.13.0

Added 1
  • Added a ttl parameter to the anyio.functools.lru_cache wrapper
Changed 1
  • Widened the type annotations of file I/O streams to accept IO[bytes] instead of just BinaryIO
Fixed 7
  • Fixed anyio.Path not being compatible with Python 3.15 due to the removal of pathlib.Path.is_reserved() and the addition of pathlib.Path.__vfspath__()
  • Fixed the BrokenResourceError raised by the asyncio SocketStream not having the original exception as its cause
  • Fixed the TypeError raised when using "func" as a parameter name in pytest.mark.parametrize when using the pytest plugin
  • Fixed the pytest plugin not running tests that had the anyio marker added programmatically via pytest_collection_modifyitems
  • Fixed cancellation exceptions leaking from a CancelScope on asyncio when they are contained in an exception group alongside non-cancellation exceptions
  • Fixed Condition.wait() not passing on a notification when the task is cancelled but already received a notification
  • Fixed inverted condition in the process pool shutdown phase which would cause still-running pooled processes not to be terminated
Removed 1
  • Dropped support for Python 3.9
  • Dropped support for Python 3.9
  • Added a ttl parameter to the anyio.functools.lru_cache wrapper (#1073; PR by @Graeme22)
  • Widened the type annotations of file I/O streams to accept IO[bytes] instead of just BinaryIO (#1078)
  • Fixed anyio.Path not being compatible with Python 3.15 due to the removal of pathlib.Path.is_reserved() and the addition of pathlib.Path.__vfspath__() (#1061; PR by @veeceey)
  • Fixed the BrokenResourceError raised by the asyncio SocketStream not having the original exception as its cause (#1055; PR by @veeceey)
  • Fixed the TypeError raised when using "func" as a parameter name in pytest.mark.parametrize when using the pytest plugin (#1068; PR by @JohnnyDeuss)
  • Fixed the pytest plugin not running tests that had the anyio marker added programmatically via pytest_collection_modifyitems (#422; PR by @chbndrhnns)
  • Fixed cancellation exceptions leaking from a CancelScope on asyncio when they are contained in an exception group alongside non-cancellation exceptions (#1091; PR by @gschaffner)
  • Fixed Condition.wait() not passing on a notification when the task is cancelled but already received a notification
  • Fixed inverted condition in the process pool shutdown phase which would cause still-running pooled processes not to be terminated (#1074; PR by @bysiber)

4.12.1

Changed 1
  • Changed all functions currently raising the private NoCurrentAsyncBackend exception to instead raise the public NoEventLoopError exception
Fixed 1
  • Fixed anyio.functools.lru_cache not working with instance methods
  • Changed all functions currently raising the private NoCurrentAsyncBackend exception (since v4.12.0) to instead raise the public NoEventLoopError exception (#1048)
  • Fixed anyio.functools.lru_cache not working with instance methods (#1042)

4.12.0

Added 7
  • Support for asyncio's task call graphs on Python 3.14 and later when using AnyIO's task groups
  • Asynchronous implementation of the functools module
  • Support for uvloop=True on Windows via the winloop implementation
  • Support for use as a context manager to anyio.lowlevel.RunVar
  • __all__ declarations to public submodules such as anyio.lowlevel
  • Ability to set the token count of a CapacityLimiter to zero
  • Parameters case_sensitive and recurse_symlinks along with support for path-like objects to anyio.Path.glob() and anyio.Path.rglob()
Changed 1
  • Dropped sniffio as a direct dependency and added the get_available_backends() function
Fixed 5
  • Process.stdin.send() not raising ClosedResourceError and BrokenResourceError on asyncio
  • Process.stdin.send() not checkpointing before writing data on asyncio
  • Race condition where cancelling a Future from BlockingPortal.start_task_soon() would sometimes not cancel the async function
  • Pytest plugin causing breakage with older versions of pytest
  • RuntimeError: Set changed size during iteration while shutting down the process pool when using the asyncio backend
  • Added support for asyncio's task call graphs on Python 3.14 and later when using AnyIO's task groups (#1025)
  • Added an asynchronous implementation of the functools module (#1001)
  • Added support for uvloop=True on Windows via the winloop implementation (#960; PR by @Vizonex)
  • Added support for use as a context manager to anyio.lowlevel.RunVar (#1003)
  • Added __all__ declarations to public submodules (anyio.lowlevel etc.) (#1009)
  • Added the ability to set the token count of a CapacityLimiter to zero (#1019; requires Python 3.10 or later when using Trio)
  • Added parameters case_sensitive and recurse_symlinks along with support for path-like objects to anyio.Path.glob() and anyio.Path.rglob() (#1033; PR by @northisup)
  • Dropped sniffio as a direct dependency and added the get_available_backends() function (#1021)
  • Fixed Process.stdin.send() not raising ClosedResourceError and BrokenResourceError on asyncio. Previously, a non-AnyIO exception was raised in such cases (#671; PR by @gschaffner)
  • Fixed Process.stdin.send() not checkpointing before writing data on asyncio (#1002; PR by @gschaffner)
  • Fixed a race condition where cancelling a Future from BlockingPortal.start_task_soon() would sometimes not cancel the async function (#1011; PR by @gschaffner)
  • Fixed the presence of the pytest plugin causing breakage with older versions of pytest (<= 6.1.2) (#1028; PR by @saper)
  • Fixed a rarely occurring RuntimeError: Set changed size during iteration while shutting down the process pool when using the asyncio backend (#985)

4.11.0

Added 4
  • Support for cancellation reasons through the `reason` parameter to `CancelScope.cancel()`
  • Ability to enter the event loop from foreign threads by passing the return value of `anyio.lowlevel.current_token()` to `anyio.from_thread.run()` and `anyio.from_thread.run_sync()` as the `token` keyword argument
  • Pytest option `anyio_mode = "auto"` to make the pytest plugin automatically handle all async tests
  • The `anyio.Condition.wait_for()` method for feature parity with asyncio
Changed 2
  • Minimum version of Trio bumped to v0.31.0
  • Default type argument of `anyio.abc.TaskStatus` changed from `Any` to `None`
Fixed 2
  • TCP listener behavior to guarantee the same ephemeral port is used for all socket listeners when `local_port=0`
  • Inconsistency between Trio and asyncio where a closed TCP stream now raises `ClosedResourceError` instead of `BrokenResourceError` on both backends
  • Added support for cancellation reasons (the reason parameter to CancelScope.cancel()) (#975)
  • Bumped the minimum version of Trio to v0.31.0
  • Added the ability to enter the event loop from foreign (non-worker) threads by passing the return value of anyio.lowlevel.current_token() to anyio.from_thread.run() and anyio.from_thread.run_sync() as the token keyword argument (#256)
  • Added pytest option (anyio_mode = "auto") to make the pytest plugin automatically handle all async tests (#971)
  • Added the anyio.Condition.wait_for() method for feature parity with asyncio (#974)
  • Changed the default type argument of anyio.abc.TaskStatus from Any to None (#964)
  • Fixed TCP listener behavior to guarantee the same ephemeral port is used for all socket listeners when local_port=0 (#857; PR by @11kkw and @agronholm)
  • Fixed inconsistency between Trio and asyncio where a TCP stream that previously raised a BrokenResourceError on send() would still raise BrokenResourceError after the stream was closed on asyncio, but ClosedResourceError on Trio. They now both raise a ClosedResourceError in this scenario. (#671)

4.10.0

Added 7
  • Add the `feed_data()` method to the `BufferedByteReceiveStream` class to inject data directly into the buffer
  • Add class methods `from_socket()` to `SocketListener`, `SocketStream`, `UNIXSocketStream`, `UDPSocket`, `ConnectedUDPSocket`, `UNIXDatagramSocket`, and `ConnectedUNIXDatagramSocket` to wrap existing sockets
  • Add a hierarchy of connectable stream classes for transparently connecting to various remote or local endpoints for exchanging bytes or objects
  • Add context manager mix-in classes `anyio.ContextManagerMixin` and `anyio.AsyncContextManagerMixin` to help write classes that embed other context managers
  • Add the ability to specify the thread name in `start_blocking_portal()`
  • Add `anyio.notify_closing` to allow waking `anyio.wait_readable` and `anyio.wait_writable` before closing a socket
  • Add a documentation page explaining why one might want to use AnyIO's APIs instead of asyncio's
Changed 1
  • Update the `to_interpreters` module to use the public `concurrent.interpreters` API on Python 3.14 or later
Fixed 7
  • Fix `anyio.Path.copy()` and `anyio.Path.copy_into()` failing on Python 3.14.0a7
  • Fix return annotation of `__aexit__` on async context managers to return `bool` when suppressing exceptions or `None` otherwise
  • Fix rollover boundary check in `SpooledTemporaryFile` so that rollover only occurs when the buffer size exceeds `max_size`
  • Fix compatibility of `anyio.to_interpreter` with Python 3.14.0b2
  • Fix `SyntaxWarning` on Python 3.14 about `return` in `finally`
  • Fix RunVar name conflicts so that RunVar instances with the same name do not share storage
  • Fix an edge case in `CapacityLimiter` on asyncio where a cancelled task is subsequently granted a token but fails to notify the next waiting task
Deprecated 1
  • Deprecate the `BrokenWorkerIntepreter` exception name in favor of `BrokenWorkerInterpreter`
  • Added the feed_data() method to the BufferedByteReceiveStream class, allowing users to inject data directly into the buffer
  • Added various class methods to wrap existing sockets as listeners or socket streams:
    • SocketListener.from_socket()
    • SocketStream.from_socket()
    • UNIXSocketStream.from_socket()
    • UDPSocket.from_socket()
    • ConnectedUDPSocket.from_socket()
    • UNIXDatagramSocket.from_socket()
    • ConnectedUNIXDatagramSocket.from_socket()
  • Added a hierarchy of connectable stream classes for transparently connecting to various remote or local endpoints for exchanging bytes or objects
  • Added context manager mix-in classes (anyio.ContextManagerMixin and anyio.AsyncContextManagerMixin) to help write classes that embed other context managers, particularly cancel scopes or task groups (#905; PR by @agronholm and @tapetersen)
  • Added the ability to specify the thread name in start_blocking_portal() (#818; PR by @davidbrochart)
  • Added anyio.notify_closing to allow waking anyio.wait_readable and anyio.wait_writable before closing a socket. Among other things, this prevents an OSError on the ProactorEventLoop. (#896; PR by @graingert)
  • Incorporated several documentation improvements from the EuroPython 2025 sprint (special thanks to the sprinters: Emmanuel Okedele, Jan Murre, Euxenia Miruna Goia and Christoffer Fjord)
  • Added a documentation page explaining why one might want to use AnyIO's APIs instead of asyncio's
  • Updated the to_interpreters module to use the public concurrent.interpreters API on Python 3.14 or later
  • Fixed anyio.Path.copy() and anyio.Path.copy_into() failing on Python 3.14.0a7
  • Fixed return annotation of __aexit__ on async context managers. CMs which can suppress exceptions should return bool, or None otherwise. (#913; PR by @Enegg)
  • Fixed rollover boundary check in SpooledTemporaryFile so that rollover only occurs when the buffer size exceeds max_size (#915; PR by @11kkw)
  • Migrated testing and documentation dependencies from extras to dependency groups
  • Fixed compatibility of anyio.to_interpreter with Python 3.14.0b2 (#926; PR by @hroncok)
  • Fixed SyntaxWarning on Python 3.14 about return in finally (#816)
  • Fixed RunVar name conflicts. RunVar instances with the same name should not share storage (#880; PR by @vimfu)
  • Renamed the BrokenWorkerIntepreter exception to BrokenWorkerInterpreter. The old name is available as a deprecated alias. (#938; PR by @ayussh-verma)
  • Fixed an edge case in CapacityLimiter on asyncio where a task, waiting to acquire a limiter gets cancelled and is subsequently granted a token from the limiter, but before the cancellation is delivered, and then fails to notify the next waiting task (#947)

4.9.0

Added 7
  • Add async support for temporary file handling
  • Add free_tcp_port_factory fixture to the pytest plugin for session-scoped generation of unused TCP port numbers
  • Add free_udp_port_factory fixture to the pytest plugin for session-scoped generation of unused UDP port numbers
  • Add free_tcp_port fixture to the pytest plugin for function-scoped generation of a free TCP port number
  • Add free_udp_port fixture to the pytest plugin for function-scoped generation of a free UDP port number
  • Add stdin argument to anyio.run_process()
  • Add the info property to anyio.Path on Python 3.14
Changed 2
  • Change anyio.getaddrinfo() to ignore invalid IPv6 name resolution results when IPv6 support is disabled in Python
  • Change EndOfStream raised from MemoryObjectReceiveStream.receive() to exclude the AttributeError from the exception chain
Fixed 4
  • Fix traceback formatting growing quadratically with level of TaskGroup nesting on asyncio due to exception chaining when raising ExceptionGroups in TaskGroup.__aexit__
  • Fix anyio.Path.iterdir() making a blocking call in Python 3.13
  • Fix connect_tcp() producing cyclic references in tracebacks when raising exceptions
  • Fix anyio.to_thread.run_sync() needlessly holding on to references of the context, function, arguments and others until the next work item on asyncio
  • Added async support for temporary file handling (#344; PR by @11kkw)
  • Added 4 new fixtures for the AnyIO pytest plugin:
    • free_tcp_port_factory: session scoped fixture returning a callable that generates unused TCP port numbers
    • free_udp_port_factory: session scoped fixture returning a callable that generates unused UDP port numbers
    • free_tcp_port: function scoped fixture that invokes the free_tcp_port_factory fixture to generate a free TCP port number
    • free_udp_port: function scoped fixture that invokes the free_udp_port_factory fixture to generate a free UDP port number
  • Added stdin argument to anyio.run_process() akin to what anyio.open_process(), asyncio.create_subprocess(), trio.run_process(), and subprocess.run() already accept (PR by @jmehnle)
  • Added the info property to anyio.Path on Python 3.14
  • Changed anyio.getaddrinfo() to ignore (invalid) IPv6 name resolution results when IPv6 support is disabled in Python
  • Changed EndOfStream raised from MemoryObjectReceiveStream.receive() to leave out the AttributeError from the exception chain which was merely an implementation detail and caused some confusion
  • Fixed traceback formatting growing quadratically with level of TaskGroup nesting on asyncio due to exception chaining when raising ExceptionGroups in TaskGroup.__aexit__ (#863; PR by @tapetersen)
  • Fixed anyio.Path.iterdir() making a blocking call in Python 3.13 (#873; PR by @cbornet and @agronholm)
  • Fixed connect_tcp() producing cyclic references in tracebacks when raising exceptions (#809; PR by @graingert)
  • Fixed anyio.to_thread.run_sync() needlessly holding on to references of the context, function, arguments and others until the next work item on asyncio (PR by @Wankupi)

4.8.0

Added 2
  • Added experimental support for running functions in subinterpreters on Python 3.13 and later
  • Added support for the copy(), copy_into(), move() and move_into() methods in anyio.Path, available in Python 3.14
Changed 2
  • Changed TaskGroup on asyncio to always spawn tasks non-eagerly, even if using a task factory created via asyncio.create_eager_task_factory(), to preserve expected Trio-like task scheduling semantics
  • Configure SO_RCVBUF, SO_SNDBUF and TCP_NODELAY on the selector thread waker socket pair to improve the performance of wait_readable() and wait_writable() when using the ProactorEventLoop
Fixed 2
  • Fixed AssertionError when using nest-asyncio
  • Fixed return type annotation of various context managers' __exit__ method
  • Added experimental support for running functions in subinterpreters on Python 3.13 and later
  • Added support for the copy(), copy_into(), move() and move_into() methods in anyio.Path, available in Python 3.14
  • Changed TaskGroup on asyncio to always spawn tasks non-eagerly, even if using a task factory created via asyncio.create_eager_task_factory(), to preserve expected Trio-like task scheduling semantics (PR by @agronholm and @graingert)
  • Configure SO_RCVBUF, SO_SNDBUF and TCP_NODELAY on the selector thread waker socket pair (this should improve the performance of wait_readable() and wait_writable() when using the ProactorEventLoop) (#836; PR by @graingert)
  • Fixed AssertionError when using nest-asyncio (#840)
  • Fixed return type annotation of various context managers' __exit__ method (#847; PR by @Enegg)
View all

Discussion