# What changed in anyio

> 98 changes in anyio 4 from its official release notes, upgrade guides and advisories: 6 breaking, 3 security, 26 new APIs and options. Each one cited. Sources checked 2026-10-17. HTML: https://unstale.sh/pypi/anyio/

To see which of these apply to a repository, run `npx @unstale/cli init` in it.

## anyio 4

### Breaking changes

- Now raises ValueError for an empty stem with a non-empty suffix instead of silently producing an incorrect path. (4.15.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.15.0)
- Raises ValueError when max_bytes is not a positive integer. (4.14.2) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.14.2)
- Support for Python 3.9 was dropped. (4.13.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.13.0)
- Functions that raised the private NoCurrentAsyncBackend exception now raise the public NoEventLoopError exception. (4.12.1) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.12.1)
- AnyIO adds get_available_backends() for discovering available backends. (4.12.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.12.0)
- sniffio is no longer a direct dependency of AnyIO. (4.12.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.12.0)

### Security

- anyio.open_process() and run_process() now pass the extra_groups argument correctly. (4.14.2) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.14.2), [security advisory](https://github.com/advisories/GHSA-3W57-8XMC-8V26)
- Matches internationalized host names against peer certificates using IDNA 2008 instead of IDNA 2003. (4.14.2) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.14.2), [security advisory](https://github.com/advisories/GHSA-82R6-8W77-94W6)
- No longer deadlocks when the worker writes enough data to fill the undrained stderr pipe. (4.14.2) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.14.2), [security advisory](https://github.com/advisories/GHSA-5P39-CFHJ-2XMP)

### New APIs and options

- Adds a utility function to simplify common asynchronous mapping patterns. (4.15.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.15.0)
- Adds a pytest command-line alternative to the anyio_mode ini setting. (4.15.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.15.0)
- Adds a synchronization primitive that lets tasks wait for a value or exception from another task. (4.15.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.15.0)
- Supports the standard library's newer follow_symlinks keyword on Python 3.12 and later. (4.15.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.15.0)
- Supports the standard library's newer follow_symlinks keyword on Python 3.13 and later. (4.15.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.15.0)
- Supports the standard library's newer follow_symlinks keyword on Python 3.13 and later. (4.15.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.15.0)
- Supports the standard library's newer follow_symlinks keyword on Python 3.13 and later. (4.15.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.15.0)
- Supports the standard library's newer follow_symlinks keyword on Python 3.13 and later. (4.15.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.15.0)
- Supports the standard library's newer newline keyword on Python 3.13 and later. (4.15.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.15.0)
- Adds a utility function to simplify common asynchronous completion-order patterns. (4.15.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.15.0)
- Accepts reason context that is included when TimeoutError is raised; the parameter also applies to fail_at. (4.15.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.15.0)
- Adds an absolute-deadline counterpart to fail_after. (4.15.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.15.0)
- Adds a utility function to simplify common asynchronous gathering patterns. (4.15.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.15.0)
- Adds an absolute-deadline counterpart to move_on_after. (4.15.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.15.0)
- Delegates nonblocking sends to the underlying ObjectSendStream when supported. (4.15.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.15.0)
- An asynchronous implementation of the itertools module is now available. (4.14.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.14.0)
- Async path and file I/O functions and classes now accept custom capacity limiters. (4.14.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.14.0)
- connect_tcp() can bind to a specific local port before connecting. (4.14.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.14.0)
- TaskGroup now has cancel() as a shortcut for cancelling its cancel scope. (4.14.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.14.0)
- Task groups now provide create_task(), returning a TaskHandle for easier asyncio migration. (4.14.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.14.0)
- TaskGroup.start() can return a TaskHandle containing the start value in start_value. (4.14.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.14.0)
- The lru_cache wrapper now accepts a ttl parameter. (4.13.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.13.0)
- anyio.Path.glob() and anyio.Path.rglob() now support path-like objects. (4.12.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.12.0)
- anyio.Path.glob() accepts the case_sensitive parameter. (4.12.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.12.0)
- anyio.Path.glob() accepts the recurse_symlinks parameter. (4.12.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.12.0)
- AnyIO adds an asynchronous implementation of the functools module. (4.12.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.12.0)

### Performance

- Reduces unnecessary CPU spin when delivering cancellation on asyncio under certain nesting conditions. (4.14.2) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.14.2)
- CancelScope and its subclasses now define __slots__ with __weakref__. (4.14.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.14.0)
- CapacityLimiter and its subclasses now define __slots__ with __weakref__. (4.14.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.14.0)
- Condition and its subclasses now define __slots__ with __weakref__. (4.14.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.14.0)
- Event and its subclasses now define __slots__ with __weakref__. (4.14.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.14.0)
- Lock and its subclasses now define __slots__ with __weakref__. (4.14.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.14.0)
- ResourceGuard and its subclasses now define __slots__ with __weakref__. (4.14.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.14.0)
- Semaphore and its subclasses now define __slots__ with __weakref__. (4.14.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.14.0)

### Behavior and default changes

- Default task names now match analogous start_soon and start tasks in more situations, including the module name. (4.15.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.15.0)
- The callable annotation now requires a callable returning a coroutine-like object instead of an arbitrary awaitable. (4.14.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.14.0)
- Path methods returning path objects now preserve subclass types by returning Self. (4.14.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.14.0)
- write_bytes() now accepts any ReadableBuffer, including bytearray and memoryview. (4.14.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.14.0)
- anyio.run() now supports callables returning arbitrary awaitables at runtime on all backends. (4.14.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.14.0)
- Errors for unavailable known backends now suggest the install command. (4.14.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.14.0)
- start_soon() now returns a TaskHandle. (4.14.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.14.0)
- The callable annotation now requires a callable returning a coroutine-like object instead of an arbitrary awaitable. (4.14.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.14.0)
- The callable annotation now requires a callable returning a coroutine-like object instead of an arbitrary awaitable. (4.14.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.14.0)
- File I/O stream annotations now accept IO[bytes] instead of only BinaryIO. (4.13.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.13.0)
- Public AnyIO submodules now define __all__ declarations, affecting wildcard imports and public-name introspection. (4.12.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.12.0)
- RunVar can now be used as a context manager. (4.12.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.12.0)
- A CapacityLimiter can now have a token count of zero. (4.12.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.12.0)

### Fixes and other changes

- Direct access to anyio.* submodules now works from the main package without importing those submodules first. (4.15.1) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.15.1)
- Pytest auto mode detection now recognizes the mode from either the ini setting or command-line option. (4.15.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.15.0)
- Stops anyio.run from leaking or delaying collection of the event loop and root task. (4.15.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.15.0)
- Fixes a race that could raise RuntimeError when the event loop closed before a worker result was scheduled. (4.15.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.15.0)
- Prevents the asyncio backend from over-granting tokens when total_tokens increases while the limiter is over-subscribed. (4.15.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.15.0)
- Prevents asyncio task groups from leaking unawaited coroutines when a custom task constructor fails. (4.15.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.15.0)
- Fixes Python 3.14 free-threading issues affecting start_blocking_portal and to_thread.run_sync context behavior. (4.15.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.15.0)
- Removes use of the deprecated pytest alias that caused warnings on pytest 9.2 and startup crashes when warnings were errors. (4.15.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.15.0)
- Prevents readinto from reading twice before rollover, which previously overwrote buffers and advanced the file position twice. (4.15.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.15.0)
- Prevents readinto1 from reading twice before rollover, which previously overwrote buffers and advanced the file position twice. (4.15.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.15.0)
- Aligns Trio and asyncio cancellation behavior, started values, and CancelledError handling when startup is cancelled. (4.15.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.15.0)
- Fixes missing parts of the default task name for tasks started with TaskGroup.start on Trio. (4.15.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.15.0)
- Ensures cleanup runs in a shielded cancel scope when the host task is cancelled while exiting the context manager. (4.15.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.15.0)
- Prevents asyncio.InvalidStateError when closing concurrently with a just-cancelled receive or send operation. (4.15.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.15.0)
- Accepts positive infinity consistently when instantiated outside an event loop. (4.14.2) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.14.2)
- Raises anyio.WouldBlock consistently on the trio backend when no tokens are available. (4.14.2) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.14.2)
- No longer over-grants tokens during the window before a notified waiter resumes on asyncio. (4.14.2) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.14.2)
- CapacityLimiter.total_tokens now accepts 0 when the limiter is instantiated outside an event loop, matching documented behavior. (4.14.1) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.14.1)
- Teardown no longer fails on asyncio when an async test raises an outcome exception such as pytest.skip(), pytest.xfail(), or pytest.fail(). (4.14.1) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.14.1)
- Cancelled waiters no longer cause asyncio Lock deadlocks during release. (4.14.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.14.0)
- backend_options now reach trio.run() when using the Trio backend. (4.14.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.14.0)
- Cancelled waiters no longer cause asyncio Semaphore deadlocks during release. (4.14.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.14.0)
- Tasks started through a BlockingPortal can now be cancelled after the portal has stopped. (4.14.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.14.0)
- On asyncio, aclose() now waits until the underlying socket file descriptor is released. (4.14.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.14.0)
- Passing arguments to lru_cache no longer loses type information. (4.14.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.14.0)
- AnyIO now supports running on Python 3.15. (4.14.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.14.0)
- AF_UNIX listening sockets are no longer incorrectly returned as TCP listeners. (4.14.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.14.0)
- to_process workers now import __main__ when entrypoint scripts lack a .py suffix, including console_script entrypoints. (4.14.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.14.0)
- On asyncio, aclose() now waits until the underlying socket file descriptor is released. (4.14.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.14.0)
- The pytest plugin now runs tests marked programmatically through pytest_collection_modifyitems. (4.13.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.13.0)
- Fixed compatibility with Python 3.15 pathlib changes. (4.13.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.13.0)
- Asyncio SocketStream errors now preserve the original exception as their cause. (4.13.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.13.0)
- Asyncio cancellation exceptions no longer leak from exception groups containing non-cancellation exceptions. (4.13.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.13.0)
- A notification is now passed on when cancellation occurs after the task already received it. (4.13.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.13.0)
- Still-running pooled processes are now terminated during process pool shutdown. (4.13.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.13.0)
- Using func as a parameter name no longer raises TypeError with the pytest plugin. (4.13.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.13.0)
- Fixed lru_cache so it works with instance methods. (4.12.1) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.12.1)
- Cancelling a Future returned by BlockingPortal.start_task_soon() now reliably cancels the async function. (4.12.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.12.0)
- The asyncio backend avoids a rare RuntimeError while shutting down the process pool. (4.12.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.12.0)
- On asyncio, Process.stdin.send() now raises ClosedResourceError and BrokenResourceError in the relevant closed or broken cases. (4.12.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.12.0)
- On asyncio, Process.stdin.send() now checkpoints before writing data. (4.12.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.12.0)
- The pytest plugin no longer breaks compatibility with pytest 6.1.2 and older. (4.12.0) — [release notes](https://github.com/agronholm/anyio/releases/tag/4.12.0)
