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

On this page
4.14.2
- 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 - 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 - 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
4.14.0
- 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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
And 37 more in this version.
4.13.0
- 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 - 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 - 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 - Signature changed
anyio.streams.file.FileReadStream.__init__
Was def __init__(self, file: BinaryIO); now def __init__(self, file: IO[bytes]). pypi.org - Signature changed
anyio.streams.file.FileStreamAttribute.file
Was file: BinaryIO; now file: IO[bytes]. pypi.org - Signature changed
anyio.streams.file.FileWriteStream.__init__
Was def __init__(self, file: BinaryIO); now def __init__(self, file: IO[bytes]). pypi.org
4.12.1
- Removed
anyio.abc.AsyncBackend.create_blocking_portal
AsyncBackend.create_blocking_portal was removed in anyio 4.12.1 pypi.org - Removed
anyio.abc.BlockingPortal.__new__
BlockingPortal.__new__ was removed in anyio 4.12.1 pypi.org - 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 - 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
4.12.0
- Removed
anyio.from_thread.CancelScope
anyio.from_thread.CancelScope was removed in anyio 4.12.0 pypi.org - Removed
anyio.from_thread.create_task_group
anyio.from_thread.create_task_group was removed in anyio 4.12.0 pypi.org - Removed
anyio.from_thread.Event
anyio.from_thread.Event was removed in anyio 4.12.0 pypi.org - Removed
anyio.from_thread.EventLoopToken
anyio.from_thread.EventLoopToken was removed in anyio 4.12.0 pypi.org - Removed
anyio.from_thread.get_async_backend
anyio.from_thread.get_async_backend was removed in anyio 4.12.0 pypi.org - Removed
anyio.from_thread.get_cancelled_exc_class
anyio.from_thread.get_cancelled_exc_class was removed in anyio 4.12.0 pypi.org - Removed
anyio.from_thread.NoEventLoopError
anyio.from_thread.NoEventLoopError was removed in anyio 4.12.0 pypi.org - Removed
anyio.from_thread.PosArgsT
anyio.from_thread.PosArgsT was removed in anyio 4.12.0 pypi.org - Removed
anyio.from_thread.run_eventloop
anyio.from_thread.run_eventloop was removed in anyio 4.12.0 pypi.org - Removed
anyio.from_thread.T_co
anyio.from_thread.T_co was removed in anyio 4.12.0 pypi.org
And 115 more in this version.
4.11.0
- Renamed
anyio.from_thread.AsyncBackend
Use anyio.lowlevel.AsyncBackend instead. pypi.org - 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 - 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 - Configuration changed
Users of Trio older than 0.31.0 must upgrade Trio to install or run this release. github.com - Signature changed
anyio.CancelScope.cancel
Was def cancel(self) -> None; now def cancel(self, reason: str | None = None) -> None. pypi.org - 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 - 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 - Signature changed
anyio.lowlevel.current_token
Was def current_token() -> object; now def current_token() -> EventLoopToken. pypi.org - Signature changed
anyio.pytest_plugin.pytest_configure
Was def pytest_configure(config: Any) -> None; now def pytest_configure(config: pytest.Config) -> None. pypi.org - 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
Check your code
These are the changes. To see which of them reach your code, scan a public repository, or have your coding agent call check_code with your manifest or lockfile over MCP. The 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.
Tell your agent what changed since it was trained.
claude mcp add --transport http since https://api.since.dev/mcp