- Support for the `follow_symlinks` keyword-only argument on `anyio.Path.exists()` (Python 3.12+)
- Support for the `follow_symlinks` keyword-only argument on `anyio.Path.is_dir()` (Python 3.13+)
- Support for the `follow_symlinks` keyword-only argument on `anyio.Path.is_file()` (Python 3.13+)
- Support for the `follow_symlinks` keyword-only argument on `anyio.Path.owner()` (Python 3.13+)
- Support for the `follow_symlinks` keyword-only argument on `anyio.Path.group()` (Python 3.13+)
- Support for the `newline` keyword-only argument on `anyio.Path.read_text()` (Python 3.13+)
- Added `amap`, `gather`, and `as_completed` utility functions to simplify common patterns
- Added `--anyio-mode` command-line option as an alternative to the `anyio_mode` ini setting
- Added the `anyio.Future` synchronization primitive which behaves similar to `asyncio.Future`
- Added `StapledObjectStream.send_nowait()` that delegates to the underlying `ObjectSendStream`, if it implements it
- Added the `move_on_at()` and `fail_at()` functions to complement `move_on_after()` and `fail_after()`
- Added a `reason` parameter to `fail_after` and the new `fail_at` allowing for added exception context when raising `TimeoutError`
- Changed the default name for a task spawned with `TaskGroup.create_task()` to match the default task name for the analogous task spawned with `TaskGroup.start_soon()` or `TaskGroup.start()` in more situations
- Changed the `anyio` and `anyio.abc` modules to lazily import the necessary submodules using AST parsing of the `if TYPE_CHECKING:` block
- Fixed the pytest plugin's auto mode detection to recognize the mode when set via either `--anyio-mode` or `anyio_mode` ini setting
- Fixed free-threading compatibility issues on Python 3.14 free-threading builds where newly created threads inherit the current context by default
- Fixed `SpooledTemporaryFile.readinto()` and `readinto1()` reading twice before rollover, causing data loss
- Fixed the default `TaskHandle.name` missing part of the task name for tasks started with `TaskGroup.start` on Trio
- Fixed `anyio.run` leaking or delaying collection of loop and root_task due to the root task being cached in a `RunVar`
From anyio
-
Added support for the newer keyword-only arguments on
anyio.Pathmethods to match the standard librarypathlib.Path:follow_symlinksonexists()(Python 3.12+)follow_symlinksonis_dir()(Python 3.13+)follow_symlinksonis_file()(Python 3.13+)follow_symlinksonowner()(Python 3.13+)follow_symlinksongroup()(Python 3.13+)newlineonread_text()(Python 3.13+)
-
Added
amap,gather, andas_completedutility functions to simplify common patterns (#1173; PR by @Graeme22) -
Added
--anyio-modecommand-line option as an alternative to theanyio_modeini setting, and fix the pytest plugin's auto mode detection to recognize the mode when set via either mechanism(e.g:pytest_asyncio). (#1242; PR by @EmmanuelNiyonshuti) -
Added the
anyio.Futuresynchronization primitive which behaves similar toasyncio.Future, allowing tasks to wait for a value (or exception) from another task (#1146; PR by @Vizonex) -
Added guidance for managing multiple memory object stream producers and consumers with cloned streams (#330; PR by @nightcityblade)
-
Added
StapledObjectStream.send_nowait()that delegates to the underlyingObjectSendStream, if it implements it (#1241; PR by @davidbrochart) -
Added the
move_on_at()andfail_at()functions to complementmove_on_after()andfail_after() -
Changed the default name for a task spawned with
TaskGroup.create_task(func())to match the default task name for the analogous task spawned withTaskGroup.start_soon(func)orTaskGroup.start(func)in more situations. Previously, the default name of aTaskGroup.create_tasktask never included the module name. (The default name for a task spawned withTaskGroup.start_soonorTaskGroup.starttypically includes the module name.) (#1234; PR by @gschaffner) -
Changed the
anyioandanyio.abcmodules to lazily (much like810) import the necessary submodules. This is done by parsing the AST of the module and building a lookup table from theif TYPE_CHECKING:block. A fallback mode has been provided for installations where the source code is unavailable (e.g. PyInstaller). (#1169) -
Fixed free-threading compatibility issues arising from the fact that on Python 3.14 free-threading builds, newly created threads inherit the current context by default, causing AnyIO to behave erroneously in relation to
start_blocking_portal()andanyio.to_thread.run_sync()(#1224; PR by @EmmanuelNiyonshuti) -
Fixed
SpooledTemporaryFile.readinto()andreadinto1()reading twice before rollover, so the destination buffer was overwritten by the second read and the file position advanced twice, silently losing data (#1215; PR by @c-tonneslan) -
Added a
reasonparameter tofail_after(and the newfail_at) allowing for added exception context when raisingTimeoutError(#1227; PR by @Graeme22) -
Fixed the default
TaskHandle.namemissing part of the task name for tasks started withTaskGroup.starton Trio (#1231; PR by @gschaffner) -
Fixed
anyio.runleaking, or at least, delaying collection of loop and root_task due to the root task being cached in aRunVar. (#1203; PR by @tapetersen) -
Fixed
anyio.Path.with_stem()silently producing a wrong path (e.g.Path(".txt")) instead of raisingValueErrorwhen given an empty stem on a path with a non-empty suffix, unlikepathlib.PurePath.with_stem(#1200; PR by @Sanjays2402) -
Fixed
UNIXSocketStream.aclose()raisingasyncio.InvalidStateErrorwhen a concurrent receive or send operation had just been cancelled on the asyncio backend (#1267; PR by @alloutflo) -
Fixed the pytest plugin importing the deprecated
_pytest.python.CallSpec2alias, which triggersPytestRemovedIn10Warningonpytest>=9.2and crashes pytest at startup whenfilterwarnings = erroris configured (#1271; PR by @matthewfeickert) -
Fixed an asyncio worker thread race that could raise
RuntimeErrorwhen the event loop closed between checking its state and scheduling the worker result (#1265; PR by @hansu650) -
Fixed
CapacityLimiteron the asyncio backend over-granting tokens whentotal_tokenswas raised while the limiter was over-subscribed (#1223; PR by @zelinewang) -
Fixed asyncio task groups leaking unawaited coroutines when a custom task constructor fails; default task creation is unaffected (#1274; PR by @dsfaccini)
-
Fixed inconsistencies between Trio and asyncio when target
TaskGroupis cancelled before a task created with.start()callsTaskStatus.started()- The started task shouldn't get a
CancelledErroruntil the first checkpoint after thestarted()call. - A value passed to
started()should be available on theTaskHandleand correctly passed back to the caller of start even if cancelled. - The CancelledError shouldn't leak out of the
TaskGroup.start()call to the calling task.
(#1197; PR by @tapetersen)
- The started task shouldn't get a
-
Fixed
TemporaryDirectorynot cleaning up when the host task was cancelled while exiting the context manager, as the cleanup now runs in a shielded cancel scope (#1304; PR by @smurfix)