---
title: "anyio Breaking Changes on PyPI | Since.dev"
description: "What each anyio release removed, renamed or changed: 221 breaking changes in 7 versions on PyPI, each with its source."
canonical_url: https://since.dev/packages/pypi/anyio
last_updated: 2026-07-12
---

# anyio breaking changes

Every breaking API change we have recorded in anyio on PyPI: 221 breaking changes in 7 versions. Below are its newest 6 versions, removals and renames first, each with its source.

Newest change July 12, 2026

## 4.14.2

3 breaking changes, first published July 12, 2026.

- **Behavior changed** `ByteReceiveStream.receive`  

Calls passing a max_bytes that is not a positive integer now raise ValueError. Pass a positive integer for max_bytes. [github.com](https://github.com/agronholm/anyio/releases/tag/4.14.2)
- **Behavior changed** `CapacityLimiter.acquire_nowait`  

On the trio backend, a failed non-blocking acquire now raises anyio.WouldBlock. Code that catches trio.WouldBlock must catch anyio.WouldBlock instead. [github.com](https://github.com/agronholm/anyio/releases/tag/4.14.2)
- **Behavior changed** `CapacityLimiter.acquire_nowait_on_behalf_of`  

On the trio backend, a failed non-blocking acquire now raises anyio.WouldBlock. Code that catches trio.WouldBlock must catch anyio.WouldBlock instead. [github.com](https://github.com/agronholm/anyio/releases/tag/4.14.2)

## 4.14.0

47 breaking changes, first published June 15, 2026.

- **Behavior changed** `anyio.CancelScope`  

Instances of these classes no longer accept arbitrary new attributes, so code or subclasses that set extra attributes on them will break. [github.com](https://github.com/agronholm/anyio/releases/tag/4.14.0)
- **Behavior changed** `anyio.CapacityLimiter`  

Instances of these classes no longer accept arbitrary new attributes, so code or subclasses that set extra attributes on them will break. [github.com](https://github.com/agronholm/anyio/releases/tag/4.14.0)
- **Behavior changed** `anyio.Condition`  

Instances of these classes no longer accept arbitrary new attributes, so code or subclasses that set extra attributes on them will break. [github.com](https://github.com/agronholm/anyio/releases/tag/4.14.0)
- **Behavior changed** `anyio.Event`  

Instances of these classes no longer accept arbitrary new attributes, so code or subclasses that set extra attributes on them will break. [github.com](https://github.com/agronholm/anyio/releases/tag/4.14.0)
- **Behavior changed** `anyio.Lock`  

Instances of these classes no longer accept arbitrary new attributes, so code or subclasses that set extra attributes on them will break. [github.com](https://github.com/agronholm/anyio/releases/tag/4.14.0)
- **Behavior changed** `anyio.ResourceGuard`  

Instances of these classes no longer accept arbitrary new attributes, so code or subclasses that set extra attributes on them will break. [github.com](https://github.com/agronholm/anyio/releases/tag/4.14.0)
- **Behavior changed** `anyio.Semaphore`  

Instances of these classes no longer accept arbitrary new attributes, so code or subclasses that set extra attributes on them will break. [github.com](https://github.com/agronholm/anyio/releases/tag/4.14.0)
- **Signature changed** `anyio.abc.AsyncBackend.run_async_from_thread`  

Was @classmethod def run_async_from_thread(cls, func: Callable\[\[Unpack\[PosArgsT\]\], Awaitable\[T_Retval\]\], args: tuple\[Unpack\[PosArgsT\]\], token: object) -> T_Retval; now @classmethod def run_async_from_thread(cls, func... [pypi.org](https://pypi.org/project/anyio/4.14.0/)
- **Signature changed** `anyio.abc.TaskGroup.start`  

The annotation now accepts only callables returning coroutine-like objects, not arbitrary awaitables. Type-checked code passing other awaitables will fail type checking. [pypi.org](https://pypi.org/project/anyio/4.14.0/)
- **Signature changed** `anyio.abc.TaskGroup.start_soon`  

start_soon() returns a TaskHandle instead of its previous return value. Code that relies on the old return value must be updated. [pypi.org](https://pypi.org/project/anyio/4.14.0/)

And 37 more in this version.

## 4.13.0

6 breaking changes, first published March 24, 2026.

- **Removed**  

Python 3.9 is no longer supported by this release; users on Python 3.9 must upgrade their interpreter or stay on an older anyio version. [github.com](https://github.com/agronholm/anyio/releases/tag/4.13.0)
- **Signature changed** `anyio.functools.AsyncLRUCacheWrapper.__init__`  

Was def \_\_init\_\_(self, func: Callable\[P, Awaitable\[T\]\], maxsize: int | None, typed: bool, always_checkpoint: bool); now def \_\_init\_\_(self, func: Callable\[P, Awaitable\[T\]\], maxsize: int | None, typed: bool, always_checkpoint: bool, ttl: int... [pypi.org](https://pypi.org/project/anyio/4.13.0/)
- **Signature changed** `anyio.functools.lru_cache`  

Was def lru_cache(func: Callable\[P, Coroutine\[Any, Any, T\]\] | Callable\[..., T\] | None = None, /, \*, maxsize: int | None = 128, typed: bool = False, always_checkpoint: bool = False) -> AsyncLRUCacheWrapper\[P, T\] |... [pypi.org](https://pypi.org/project/anyio/4.13.0/)
- **Signature changed** `anyio.streams.file.FileReadStream.__init__`  

Was def \_\_init\_\_(self, file: BinaryIO); now def \_\_init\_\_(self, file: IO\[bytes\]). [pypi.org](https://pypi.org/project/anyio/4.13.0/)
- **Signature changed** `anyio.streams.file.FileStreamAttribute.file`  

Was file: BinaryIO; now file: IO\[bytes\]. [pypi.org](https://pypi.org/project/anyio/4.13.0/)
- **Signature changed** `anyio.streams.file.FileWriteStream.__init__`  

Was def \_\_init\_\_(self, file: BinaryIO); now def \_\_init\_\_(self, file: IO\[bytes\]). [pypi.org](https://pypi.org/project/anyio/4.13.0/)

## 4.12.1

4 breaking changes, first published January 6, 2026.

- **Removed** `anyio.abc.AsyncBackend.create_blocking_portal`  

AsyncBackend.create_blocking_portal was removed in anyio 4.12.1 [pypi.org](https://pypi.org/project/anyio/4.12.1/)
- **Removed** `anyio.abc.BlockingPortal.__new__`  

BlockingPortal.\_\_new\_\_ was removed in anyio 4.12.1 [pypi.org](https://pypi.org/project/anyio/4.12.1/)
- **Behavior changed**  

Functions that previously raised the private NoCurrentAsyncBackend exception now raise the public NoEventLoopError. Code that catches NoCurrentAsyncBackend must catch NoEventLoopError instead. [github.com](https://github.com/agronholm/anyio/releases/tag/4.12.1)
- **Signature changed** `anyio.functools.AsyncLRUCacheWrapper.__init__`  

Was def \_\_init\_\_(self, func: Callable\[..., Awaitable\[T\]\], maxsize: int | None, typed: bool, always_checkpoint: bool); now def \_\_init\_\_(self, func: Callable\[P, Awaitable\[T\]\], maxsize: int | None, typed: bool, always_checkpoint: bool). [pypi.org](https://pypi.org/project/anyio/4.12.1/)

## 4.12.0

125 breaking changes, first published November 28, 2025.

- **Removed** `anyio.from_thread.CancelScope`  

anyio.from_thread.CancelScope was removed in anyio 4.12.0 [pypi.org](https://pypi.org/project/anyio/4.12.0/)
- **Removed** `anyio.from_thread.create_task_group`  

anyio.from_thread.create_task_group was removed in anyio 4.12.0 [pypi.org](https://pypi.org/project/anyio/4.12.0/)
- **Removed** `anyio.from_thread.Event`  

anyio.from_thread.Event was removed in anyio 4.12.0 [pypi.org](https://pypi.org/project/anyio/4.12.0/)
- **Removed** `anyio.from_thread.EventLoopToken`  

anyio.from_thread.EventLoopToken was removed in anyio 4.12.0 [pypi.org](https://pypi.org/project/anyio/4.12.0/)
- **Removed** `anyio.from_thread.get_async_backend`  

anyio.from_thread.get_async_backend was removed in anyio 4.12.0 [pypi.org](https://pypi.org/project/anyio/4.12.0/)
- **Removed** `anyio.from_thread.get_cancelled_exc_class`  

anyio.from_thread.get_cancelled_exc_class was removed in anyio 4.12.0 [pypi.org](https://pypi.org/project/anyio/4.12.0/)
- **Removed** `anyio.from_thread.NoEventLoopError`  

anyio.from_thread.NoEventLoopError was removed in anyio 4.12.0 [pypi.org](https://pypi.org/project/anyio/4.12.0/)
- **Removed** `anyio.from_thread.PosArgsT`  

anyio.from_thread.PosArgsT was removed in anyio 4.12.0 [pypi.org](https://pypi.org/project/anyio/4.12.0/)
- **Removed** `anyio.from_thread.run_eventloop`  

anyio.from_thread.run_eventloop was removed in anyio 4.12.0 [pypi.org](https://pypi.org/project/anyio/4.12.0/)
- **Removed** `anyio.from_thread.T_co`  

anyio.from_thread.T_co was removed in anyio 4.12.0 [pypi.org](https://pypi.org/project/anyio/4.12.0/)

And 115 more in this version.

## 4.11.0

10 breaking changes, first published September 23, 2025.

- **Renamed** `anyio.from_thread.AsyncBackend`  

Use anyio.lowlevel.AsyncBackend instead. [pypi.org](https://pypi.org/project/anyio/4.11.0/)
- **Behavior changed**  

After a TCP stream is closed, send() on asyncio now raises ClosedResourceError instead of BrokenResourceError, so code catching BrokenResourceError in this case must catch ClosedResourceError instead. [github.com](https://github.com/agronholm/anyio/releases/tag/4.11.0)
- **Default changed** `anyio.abc.TaskStatus`  

Code relying on the previous Any default type argument may see different type checking results and should specify the type argument explicitly. [github.com](https://github.com/agronholm/anyio/releases/tag/4.11.0)
- **Configuration changed**  

Users of Trio older than 0.31.0 must upgrade Trio to install or run this release. [github.com](https://github.com/agronholm/anyio/releases/tag/4.11.0)
- **Signature changed** `anyio.CancelScope.cancel`  

Was def cancel(self) -> None; now def cancel(self, reason: str | None = None) -> None. [pypi.org](https://pypi.org/project/anyio/4.11.0/)
- **Signature changed** `anyio.from_thread.run`  

Was def run(func: Callable\[\[Unpack\[PosArgsT\]\], Awaitable\[T_Retval\]\], \*args: Unpack\[PosArgsT\]) -> T_Retval; now def run(func: Callable\[\[Unpack\[PosArgsT\]\], Awaitable\[T_Retval\]\], \*args: Unpack\[PosArgsT\], token: EventLoopToken | None = None)... [pypi.org](https://pypi.org/project/anyio/4.11.0/)
- **Signature changed** `anyio.from_thread.run_sync`  

Was def run_sync(func: Callable\[\[Unpack\[PosArgsT\]\], T_Retval\], \*args: Unpack\[PosArgsT\]) -> T_Retval; now def run_sync(func: Callable\[\[Unpack\[PosArgsT\]\], T_Retval\], \*args: Unpack\[PosArgsT\], token: EventLoopToken | None = None) -> T_Retval. [pypi.org](https://pypi.org/project/anyio/4.11.0/)
- **Signature changed** `anyio.lowlevel.current_token`  

Was def current_token() -> object; now def current_token() -> EventLoopToken. [pypi.org](https://pypi.org/project/anyio/4.11.0/)
- **Signature changed** `anyio.pytest_plugin.pytest_configure`  

Was def pytest_configure(config: Any) -> None; now def pytest_configure(config: pytest.Config) -> None. [pypi.org](https://pypi.org/project/anyio/4.11.0/)
- **Signature changed** `anyio.pytest_plugin.pytest_pycollect_makeitem`  

Was def pytest_pycollect_makeitem(collector: Any, name: Any, obj: Any) -> None; now def pytest_pycollect_makeitem(collector: pytest.Module | pytest.Class, name: str, obj: object) -> None. [pypi.org](https://pypi.org/project/anyio/4.11.0/)

## Check your code

These are the changes. To see which of them reach your code, [scan a public repository](https://since.dev/scan.md), or have your coding agent call `check_code` with your manifest or lockfile over [MCP](https://since.dev/docs.md#mcp). [The API](https://since.dev/docs.md#api) reads every change in every version, not only the newest. On Team and up, a fix pull request opens for the changes that reach a connected repository. Nothing merges or deploys.

## Put your code on continuous management.

Scan a public repository now, or give your agent one line.

### See how out of date your code is.

[Scan a repository](https://since.dev/scan.md). Any public GitHub repository. No sign-in.

### Tell your agent what changed since it was trained.

`claude mcp add --transport http since https://api.since.dev/mcp`

---

Every page on this site as Markdown: https://since.dev/sitemap.md. For agents: https://since.dev/llms.txt.
