chore: update Python dependencies (uv.lock) (14 updates) #6
Loading…
Reference in a new issue
No description provided.
Delete branch "updatarr/python-dependencies--uv.lock-bbfe89acc5"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Updates
Python dependencies (uv.lock).Breaking change detected. Review the release notes before merging.
Automerge: Disabled because breaking change release notes were detected
Updates
aiohappyeyeballs2.6.12.7.1aiohttp3.13.33.14.3anyio4.14.24.15.1attrs25.4.026.1.0idna3.113.20multidict6.7.06.9.1packaging25.026.3propcache0.4.10.5.4pygments2.19.22.21.0pyrefly1.2.01.3.1ruff0.14.110.16.9typing-extensionscurrent version4.16.0watchfiles1.2.01.3.0yarl1.22.01.25.1Files
uv.lockRelease notes
aiohappyeyeballs (2.6.1 → 2.7.1)
2.6.2: v2.6.2Compare source
Source
Source ref:
mainv2.6.2 (2026-05-20)
Bug Fixes
55dd76a)Refactoring
02a7029)Testing
ce43beb)Detailed Changes: v2.6.1...v2.6.2
v2.7.0: v2.7.0Compare source
Source
Source ref:
mainv2.7.0 (2026-05-20)
Features
10e7d43)Detailed Changes: v2.6.2...v2.7.0
2.7.1: v2.7.1Compare source
Source
Source ref:
mainv2.7.1 (2026-07-01)
Performance Improvements
e10f335)Refactoring
Collapse collect-then-remove pattern in utils helpers (#227,
0dd3fd1)Merge identical except blocks in _connect_sock cleanup (#229,
b7c186e)Simplify _interleave_addrinfos family grouping (#226,
fdf6548)Detailed Changes: v2.7.0...v2.7.1
aiohttp (3.13.3 → 3.14.3)
Source comparison unavailable: source refs for this transition are not known.
3.13.43.13.53.14.03.14.13.14.23.14.3anyio (4.14.2 → 4.15.1)
4.15.0: 4.15.0Compare source
Source
Source ref:
masterAdded 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+)(#1286, #1293; PR by @jaideeppyne)
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()CancelledErroruntil the first checkpoint after thestarted()call.started()should be available on theTaskHandleand correctly passed back to the caller of start even if cancelled.TaskGroup.start()call to the calling task.(#1197; PR by @tapetersen)
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)4.15.1: 4.15.1Compare source
Source
Source ref:
masteranyio.*submodules from the main package even when those submodules were not directly imported first (#1311 <https://github.com/agronholm/anyio/issues/1311>)attrs (25.4.0 → 26.1.0)
26.1.0idna (3.11 → 3.20)
3.12Compare source
Source
Source ref:
master3.13Compare source
Source
Source ref:
master3.14Compare source
Source
Source ref:
master3.15Compare source
Source
Source ref:
master3.16Compare source
Source
Source ref:
master3.17Compare source
Source
Source ref:
master3.18Compare source
Source
Source ref:
master3.19Compare source
Source
Source ref:
masterstd3_rulesoption, which had no effect since changesto UTS #46 processing in Unicode 16. Note that
uts46_remap()defaults to enabling STD3 rules, so direct callers will see input
containing non-LDH ASCII characters rejected again.
ASCII-only domains.
thread safety.
idna.unicode_version, and show it inidna --version.code,text,codepointandpositionattributes toIDNAErrorso that the failed rule and the offending character canbe identified without parsing the exception message.
transitionalargument toencode()anduts46_remap()is now completely ignored, and gives a deprecation warningfor the latter.
their U-label.
IDNAErrorinstead ofInvalidCodepointContext.IDNAErrorfor empty labels and non-ASCII bytespassed to label helper functions and the incremental codec.
measurement, and CI checks that the data tables match the generator
output.
Thanks to stefan6419846, LouieLuNZ, and Salvatore Corvaglia for
contributions to this release.
3.20Compare source
Source
Source ref:
mastercodec.
multidict (6.7.0 → 6.9.1)
6.7.1: 6.7.1Compare source
Source
Source ref:
masterBug fixes
Fixed slow memory leak caused by identity by adding
Py_DECREFto identity value before leavingmd_pop_oneon success-- by :user:
Vizonex.Related issues and pull requests on GitHub:
#1284.
6.8.0: 6.8.0Breaking change detected.
Compare source
Source
Source ref:
masterBug fixes
A segmentation fault that could be triggered when getting an item is now fixed
-- by :user:
Vizonex.Related issues and pull requests on GitHub:
#1310.
Fixed reference leak in iterators, views and
istr-- by :user:
Vizonex.Related issues and pull requests on GitHub:
#1311.
Fixed the pure-Python :class:
~multidict.MultiDictconstructor and:py:meth:
~multidict.MultiDict.extend,:py:meth:
~multidict.MultiDict.update, and:py:meth:
~multidict.MultiDict.mergemethods over-allocating theirinternal hash table when called with both a positional argument and
keyword arguments, because keyword arguments were counted twice in the
size estimate -- by :user:
aiolibsbot.Related issues and pull requests on GitHub:
#1338.
Fixed
__repr__of :class:~multidict.MultiDict,:class:
~multidict.CIMultiDict, their proxies, and the keys/items viewsproducing invalid output when keys contained quote characters --
keys are now formatted with :func:
reprso the result is a valid Pythonstring literal -- by :user:
aiolibsbot.Related issues and pull requests on GitHub:
#1342.
Fixed a segfault when calling :py:meth:
~multidict.MultiDict.addwith only one of its two required arguments supplied by keyword, e.g.d.add(key="k"). Extra keyword arguments passed to the lookup and removal methods are also now rejected with :exc:TypeErrorinstead of being silently ignored.-- by :user:
devdanzinRelated issues and pull requests on GitHub:
#1376.
Fixed a segfault when constructing a multidict iterator type directly, e.g.
type(iter(md.keys())).__new__(...). Such an iterator had a NULL internal pointer thatnext()dereferenced. The iterator types now forbid direct instantiation, the same way the view types were fixed in #1163.-- by :user:
devdanzinRelated issues and pull requests on GitHub:
#1377.
Fixed a segfault when using a :py:class:
~multidict.MultiDictor :py:class:~multidict.CIMultiDictcreated via__new__without calling__init__(for example a subclass that does not callsuper().__init__()). The internal state was left as NULL pointers that the first method call dereferenced.tp_newnow initializes the object to a valid empty mapping.-- by :user:
devdanzinRelated issues and pull requests on GitHub:
#1378.
Fixed two crashes in the C extension caused by holding a raw pointer into a hash table across an operation that could reshape it. Updating a multidict from itself (e.g.
d.extend(d)) freed the very table being iterated -- a use-after-free;extend(self)now doubles the contents andupdate(self)/merge(self)are no-ops. Building a multidict from a list of pairs whose case-insensitive key.lower()shrinks that list read past the end of the list; the length is now re-checked on every iteration.-- by :user:
devdanzinRelated issues and pull requests on GitHub:
#1379.
Fixed three reference/resource leaks on error paths in the C extension: the items-view
__contains__leaked the first element of a candidate pair when reading the second one raised;__repr__leaked itsPyUnicodeWriterwhen the multidict was mutated during iteration; and the internal iteration helper leaked the identity reference when key materialization failed under low memory.-- by :user:
devdanzinRelated issues and pull requests on GitHub:
#1381.
Stopped several feature-detection fallbacks in the C extension from swallowing every exception. When probing an argument (
arg.items()/arg.keys()) or measuring it (len(other)) fails, the code now clears only the expected :exc:TypeError/:exc:AttributeErrorand lets everything else -- notably :exc:MemoryErrorand :exc:KeyboardInterrupt-- propagate, matching the already-correct sites elsewhere in the module.-- by :user:
devdanzinRelated issues and pull requests on GitHub:
#1382.
Fixed a segmentation fault when extending a multidict with itself
-- by :user:
cananooand :user:asvetlov.Related issues and pull requests on GitHub:
#1398.
Fixed a memory leak when
MultiDictandCIMultiDictinstances areinitialized more than once -- by :user:
asvetlov.Related issues and pull requests on GitHub:
#1412.
Fixed a reference leak in items-view set operations
-- by :user:
asvetlov.Related issues and pull requests on GitHub:
#1413.
Fixed a memory leak when destroying C-extension multidict instances
and proxies -- by :user:
asvetlov.Related issues and pull requests on GitHub:
#1415.
Fixed a reference leak from repeated
__init__calls onMultiDictProxyandCIMultiDictProxyinstances -- by :user:asvetlov.Related issues and pull requests on GitHub:
#1419.
Fixed missing decref for :data:
Noneon error in :meth:~multidict.MultiDict.setdefault-- by :user:
asvetlovRelated issues and pull requests on GitHub:
#1421.
Features
Added :py:func:
reversedsupport to the keys, values, and items views of:class:
~multidict.MultiDict, :class:~multidict.CIMultiDict, and theirproxies in both the C-extension and pure-Python implementations
-- by :user:
aiolibsbot.Related issues and pull requests on GitHub:
#448.
Optimized key identity comparison for C Extension.
Now it uses fast path that is equal to :c:func:
PyUnicode_EqualfromPython 3.14+ but without redundant type checks. It gives ~15% speed-up on benchmarks with many key comparisons.
-- by :user:
asvetlovRelated issues and pull requests on GitHub:
#1406.
Changed both the pure-Python and C implementations to mark a temporarily
removed hash table entry by setting the high bit of its hash instead of
overwriting it with a sentinel value, so restoring the entry no longer
recomputes the hash; :meth:
~multidict.MultiDict.getallis faster ~10% now in C version-- by :user:
asvetlovRelated issues and pull requests on GitHub:
#1426.
Removals and backward incompatible breaking changes
Dropped support for Python 3.9 as it has reached end of life.
Related issues and pull requests on GitHub:
#1316.
Dropped support for free-threaded Python 3.13 -- by :user:
ngoldbaum.Related issues and pull requests on GitHub:
#1326.
Improved documentation
Fixed
CIMultiDictProxydocumentation to state it inherits fromMultiDictProxy(notMultiDict), and fixed missing word inistrsection -- by :user:veeceey.Related issues and pull requests on GitHub:
#1298.
Clarified that
istrpreserves the original casing andcompares as a regular
str; case-insensitive matching ishandled by
CIMultiDict-- by :user:gyanu2507.Related issues and pull requests on GitHub:
#1397.
Fixed broken RST markup in
items()docstrings-- by :user:
veeceey.Related issues and pull requests on GitHub:
#1299.
Packaging updates and notes for downstreams
Dropped support for free-threaded Python 3.13 -- by :user:
ngoldbaum.Related issues and pull requests on GitHub:
#1326.
Wheels for iOS and Android (CPython 3.13+) are now published on
release-tag builds, so downstreams on those platforms no longer need a
local compiler to install
multidict; these wheels are build-verifiedonly, since running the test suite on mobile needs a simulator or an
emulator -- by :user:
aiolibsbot.Related issues and pull requests on GitHub:
#1337.
Added support for building and shipping riscv64 wheels
-- by :user:
justeph.Related issues and pull requests on GitHub:
#1293.
The
setuptoolsbuild dependency lower bound has been restored to be>= 47after an incorrect automated increase in :pr:1315-- by :user:
aiolibsbot.Related issues and pull requests on GitHub:
#1400.
Contributor-facing changes
Added support for collecting code coverage of isolated multidict tests
-- by :user:
Vizonex.Related issues and pull requests on GitHub:
#1314.
Switched to
mirrors-clang-formatand enabled clang-format inpre-commit.ci-- by :user:
bdraco.Related issues and pull requests on GitHub:
#1318.
Added a release-tag-gated CI job that cross-compiles the C extension
for iOS and Android through
cibuildwheel-- by :user:aiolibsbot.Related issues and pull requests on GitHub:
#1337.
Added an
AGENTS.mdorientation file at the repository root, covering thepull request template, the
CHANGES/news fragment conventions, thedraft-PR / human-review workflow, and the dual pure-Python and C-extension
parity rule, so LLM contributors land changes that match project style
-- by :user:
bdraco.Related issues and pull requests on GitHub:
#1339.
Added
init,installable,instantiation,parametrization,parametrized,postfix, andunparseableto the docs spelling listso news fragments and docs can use these words without failing the spell
check build -- by :user:
pctablet505.Related issues and pull requests on GitHub:
#1343.
Documented three common agent failure modes in
:file:
AGENTS.md: the docs spell check(
make doc-spelling) catches unknown words in news fragmentsbefore CI does; coverage runs over the test tree too, so
unreachable defensive
raiseguards and one-sided cleanupbranches in tests will surface as uncovered on the codecov
patch report; and branch creation is restricted on
aio-libs/multidict, so PRs must be pushed from a fork-- by :user:
bdraco.Related issues and pull requests on GitHub:
#1343, #1345.
Trimmed the CI test matrix to drop redundant
Py_DEBUGjobs onmacOS and Windows and to gate the
windows-11-armwheel build torelease-time only, cutting CI wall-clock by roughly a third without
reducing code coverage -- by :user:
aiolibsbot.Related issues and pull requests on GitHub:
#1346.
Added a
CLAUDE.mdat the repository root that imports:file:
AGENTS.mdvia Claude Code's@-syntax, so theproject's LLM contributor rules load automatically when
working in Claude Code
-- by :user:
aiolibsbot.Related issues and pull requests on GitHub:
#1347.
Enabled the
I(import sorting) rule in[tool.ruff.lint]soruff checkcovers import order on topof the existing
UP(pyupgrade) group, and updated theruff-checkpre-commit hook to run with--fix --exit-non-zero-on-fix --show-fixesso import-orderfixes apply on commit. Sorted imports in four
tests/filesto match the new rule -- by :user:
bdraco.Related issues and pull requests on GitHub:
#1348.
Enabled the
PLC0415(import-outside-top-level) rule in[tool.ruff.lint]. Function-scoped imports must now opt inwith
# noqa: PLC0415plus a comment explaining the reason(typically avoiding a heavy optional dependency at import time).
This catches a pattern that LLM contributors frequently introduce.
There are currently no opt-outs in the tree, so the rule is
enforced everywhere
ruff checkruns-- by :user:
bdraco.Related issues and pull requests on GitHub:
#1349.
Switched the
cibuildwheelbuild frontend tobuild[uv]sothat
uvprovisions every build and test virtual environmentin the wheel matrix. Test-dependency installation in particular
drops from a multi-second
pip installper ABI to a roughlysub-second
uvresolve-- by :user:
bdraco.Related issues and pull requests on GitHub:
#1350.
Overrode
CIBW_BUILD_FRONTEND=buildfor the odd-arch wheelmatrix; the upstream
manylinux/musllinuximages forthose arches do not ship
uv-- by :user:
bdraco.Related issues and pull requests on GitHub:
#1352.
Allowed re-running the deploy job after a partial release failure: the
Make Releasestep now skips when the GitHub Release already exists,and the PyPI publish step uses
skip-existingso dists that werealready uploaded on a prior attempt do not break the retry
-- by :user:
bdraco.Related issues and pull requests on GitHub:
#1353.
Switched the aarch64 and armv7l wheel builds to GitHub's native ARM
runners. The aarch64 wheels now build without QEMU emulation, and
armv7l runs on aarch64 hosts so its 32-bit ARM execution is far
cheaper than the previous aarch64-on-x86_64 path
-- by :user:
bdraco.Related issues and pull requests on GitHub:
#1354.
Documented design principles for pure-Python :class:
~multidict.istrimplementation-- by :user:
asvetlovRelated issues and pull requests on GitHub:
#1360.
Pinned
coverageto thectracemeasurement core so the test suite runson Python 3.14. Coverage picks
sysmonthere, which cannot record thedynamic contexts
pytest-covswitches at runtime, and the resulting warningbecame an error under the suite's
filterwarningssetting-- by :user:
rodrigobnogueira.Related issues and pull requests on GitHub:
#1393.
Dependabot has been restricted to the
requirementssubdirectory toavoid unintended updates outside dependency requirement files
-- by :user:
aiolibsbot.Related issues and pull requests on GitHub:
#1400.
Enabled automatic upgrades from ruff after each python version that is dropped
-- by :user:
Vizonex.Related issues and pull requests on GitHub:
#1325.
Miscellaneous internal changes
Explicitly marked
empty_htkeysasconst.Moved the structure to
.rodatalinker section.Unexpected modification of the structure will lead to segfault instead
of corrupting the data and fail fast.
.rodatais mount as read-only-mapped, it is shared well acrossmultiple threads without cache misses.
The change is pretty trivial, it is made for the sake of correctness,
not for speedup.
-- by :user:
asvetlov.Related issues and pull requests on GitHub:
#1405.
Slightly reorganized multidict creating process.
md_init()creates an empty multidict.tp_allocslot is used in object cloning instead of bare :c:func:PyType_GenericNewcall.-- by :user:
asvetlovRelated issues and pull requests on GitHub:
#1420.
Dropped dead code,
_md_del_at()and_md_del_at_for_upd()never fails-- by :user:
asvetlovRelated issues and pull requests on GitHub:
#1423.
Fixed a missing space in the :exc:
ValueErrormessageraised when constructing a multidict from a sequence
-- by :user:
veeceey.Related issues and pull requests on GitHub:
#1295.
Renamed the benchmark script from
benchmarks/becnhmark.pytobenchmarks/benchmark.pyso it matches the invocation documented in:doc:
benchmark-- by :user:aiolibsbot.Related issues and pull requests on GitHub:
#1335.
6.9.0: 6.9.0Compare source
Source
Source ref:
masterBug fixes
Protected
repr()ofMultiDict,MultiDictProxy, and their viewsin the C extension with a critical section, avoiding data races on the
free-threaded build of CPython -- by :user:
asvetlov.Related issues and pull requests on GitHub:
#1431.
Guarded
repr()ofMultiDictProxyin the C extension and ofKeysViewin both the C extension and the pure-Pythonimplementation against infinite recursion on self-referential
containers, matching the existing guard on
MultiDict,ItemsView, andValuesView-- by :user:asvetlov.Related issues and pull requests on GitHub:
#1431.
Protected
MultiDict.update(),.extend(),.merge(),.clear(),.copy(), and theMultiDict/CIMultiDictconstructors in the Cextension with a critical section, using the two-object form when a
second multidict, multidict proxy, or plain
dictinstance isinvolved, avoiding data races and a segmentation fault on the
free-threaded build of CPython.
.clear()now also publishes theempty table before releasing any entry's references, so a concurrent
caller can never observe a partially-cleared multidict even if releasing
a value runs arbitrary Python code that suspends the held critical
section -- by :user:
asvetlov.Related issues and pull requests on GitHub:
#1433.
Protected
MultiDict.add(),__setitem__/__delitem__,get()/getone()/__getitem__,__contains__,getall(),setdefault(),pop()/popone()/popall()/popitem(),__eq__, iteration, and the&/|/-/^/in/isdisjoint()operations on.keys()and.items()views in theC extension with a critical section, avoiding data races and
use-after-free crashes on the free-threaded build of CPython
-- by :user:
asvetlov.Related issues and pull requests on GitHub:
#1438.
Fixed a data race on the free-threaded build where
MultiDictObject.usedwas written non-atomically while
len()read it with a relaxed atomicload -- by :user:
asvetlov.Related issues and pull requests on GitHub:
#1441.
Fixed several pre-existing use-after-free races on the free-threaded build:
_md_resize()and
md_clone_from_ht()could allocate a new hash table, have theircritical section transiently suspended during that allocation, and then use
a keys-table pointer or size a concurrent operation had already invalidated;
_md_del_at()(plaindel/pop()) could likewise leaveselfinan inconsistent state across a suspending decref -- by :user:
asvetlov.Related issues and pull requests on GitHub:
#1441.
Fixed a data race on the free-threaded build where
md->keyswaspublished with a plain store while lock-free readers loaded it
atomically, and a false-negative race in
get()/__contains__where a hash temporarily marked by a concurrent replace could make a
present key look absent -- by :user:
asvetlov.Related issues and pull requests on GitHub:
#1441.
Fixed several more pre-existing use-after-free and data-corruption races on
the free-threaded build, this time in the
__setitem__()/update()/extend()/merge()replace path: a decref suspending the criticalsection mid-replace could leave a stale table pointer in use, misplace a
temporarily-marked entry during a concurrent resize, or let one thread's
duplicate-tracking mark get overwritten by an unrelated key's entry sharing
the same hash bucket -- by :user:
asvetlov.Related issues and pull requests on GitHub:
#1441.
Fixed an unbounded memory leak on the free-threaded build where a retired
hash table could sit on
md->retiredfor the rest of the object'slifetime under sustained concurrent read traffic instead of being freed
-- by :user:
asvetlov.Related issues and pull requests on GitHub:
#1443.
Fixed a data race on the free-threaded build of the C extension where
state->global_version, the version counter shared by everymultidict instance and used to derive
getversion(), was bumped witha plain increment instead of an atomic op. Two threads mutating
different instances at the same time could step on each other's update
and hand out a duplicate (or non-monotonic) version number
-- by :user:
asvetlov.Related issues and pull requests on GitHub:
#1444.
Fixed a data race on the free-threaded build of the C extension where
getall()/popall()andupdate()/extend()/merge()temporarily marked and unmarked a matching entry's hash with a plain,
non-atomic store, while a lock-free
__contains__/get()on anotherthread could load that same field with an atomic operation and no lock at
all -- by :user:
asvetlov.Related issues and pull requests on GitHub:
#1448.
Fixed a data race in the pure-Python
MultiDict/CIMultiDictfallback where concurrent mutating calls (
add(),__setitem__,__delitem__,setdefault(),pop()/popone(),popall(),popitem(),update(),extend(),merge(),clear(), and re-__init__) could corrupt the shared hash table,or silently drop a concurrent write, on a regular, GIL-enabled
interpreter. Pure-Python bytecode is not atomic under the GIL, so two
threads could interleave mid hash-table insert or deletion, leaving
the index table pointing at stale or out-of-range entries and causing
an infinite probe loop, an
AttributeError, or a lost mutation.Each
MultiDict/CIMultiDictinstance now holds its own lock forthe duration of these operations, with two-object operations locking
both instances in a fixed order to avoid deadlock. The C extension
already serializes these operations with a critical section and was
not affected
-- by :user:
asvetlov.Related issues and pull requests on GitHub:
#1449.
Fixed a data race on the free-threaded build of the C extension where
to_dict()cleared every entry's temporary "seen" mark with a plain,non-atomic store, while a lock-free
__contains__/get()on anotherthread could load that same field with an atomic operation and no lock at
all -- by :user:
asvetlov.Related issues and pull requests on GitHub:
#1450.
Fixed a data race on the free-threaded build of the C extension where
update()/extend()/merge()readself's module state withoutholding
self's lock, while a concurrent__init__()on the same,already-published multidict could rewrite that same field under lock.
Rather than routing every read through a lock-free lookup, the field is
now written only once, at object construction, and never touched again by
__init__(), so it is safe to read unlocked anywhere -- by:user:
asvetlov.Related issues and pull requests on GitHub:
#1452.
Fixed
items()set algebra (&,|,-,in,isdisjoint()) so it nolonger corrupts or hangs when a compared value's
__eq__()re-enters thesame :class:
~multidict.MultiDict, for example by callinggetall()onit. The comparison now runs only after the internal hash-chain walk has
been fully materialized and restored, so the callback can no longer
observe entries the walk still has marked -- by :user:
asvetlov.Related issues and pull requests on GitHub:
#1453.
Fixed a data race on the free-threaded build of the C extension where
popall()/popone()/__delitem__/add()rewrote a hash tableindex slot with a plain, non-atomic store, while a lock-free
get()/getone()/__getitem__/__contains__on another threadwalked that same index array with a plain, non-atomic load and no lock at
all -- by :user:
asvetlov.Related issues and pull requests on GitHub:
#1454.
Stopped folding the case of :class:
~multidict.istrkeys in thecase-sensitive :class:
~multidict.MultiDict, so both the C and the purePython implementations now keep such a key exactly as given
-- by :user:
youdie006.Related issues and pull requests on GitHub:
#1457.
Fixed the C extension's
update()(andmerge(), which shares the samecode path) silently failing to invalidate an in-progress
keys()/items()/values()iterator when the call only overwrote analready-present key's value in place. Adding a new key already invalidated
iterators correctly; only the in-place overwrite branch was missing the
version bump -- by :user:
asvetlov.Related issues and pull requests on GitHub:
#1458.
Fixed the pure-Python
MultiDict/CIMultiDictiterator guard so thatmutating the mapping before the first
next()call on anitems(),keys(), orvalues()iterator (or oniter(md)) now reliably raisesRuntimeError, matching the C extension. Previously a mutation thathappened before the iterator was ever advanced, such as
clear()or adel/popone()that removed the only remaining entry, could make theiterator silently raise
StopIterationinstead -- by :user:asvetlov.Related issues and pull requests on GitHub:
#1459.
Fixed a use-after-free race on the free-threaded build of the C extension
where a retired hash table could be freed while a lock-free
get()/getone()/__getitem__/__contains__reader on anotherthread was still walking it: the coarse "no reader in flight" gate
reaching zero did not reliably mean every such reader had also reached
its own per-table exit, so a table whose own reader count is still
nonzero is now deferred for a later retry instead of freed
-- by :user:
asvetlov.Related issues and pull requests on GitHub:
#1461.
Features
Added a :meth:
~multidict.MultiDict.to_dictmethod returning a plain:class:
dictthat maps every key to the list of all its values. Unlikedict(md), which keeps only the first value per key, and unlike a{k: md.getall(k) for k in md}comprehension, which emits one entry perspelling of a case-insensitive key, it groups by key identity
-- by :user:
rodrigobnogueira.Related issues and pull requests on GitHub:
#783.
MultiDict,CIMultiDict,MultiDictProxyandCIMultiDictProxyin theC extension implemented the vectorcall calling convention for construction.
This sped up
MultiDict(...)-style calls by avoiding an intermediatepositional-arguments tuple and keyword-arguments dictionary in the common case; the gained burst is ~10.
-- by :user:
asvetlov.Related issues and pull requests on GitHub:
#1436.
Made
MultiDict.__contains__(),.get(),.getone()and__getitem__()lock-free on CPython 3.14+'s free-threaded build, insteadof taking a critical section like the rest of the C extension's API (on
3.13, which lacks the public API these need to safely read an entry
concurrently, they still take the critical section, exactly as before). A
resize/shrink/clear no longer frees the outgoing hash table immediately; it
is deferred until no lock-free reader could still be walking it -- by
:user:
asvetlov.Related issues and pull requests on GitHub:
#1441.
Made the pure-Python
MultiDict/CIMultiDictimplementation safe touse from multiple threads under a free-threaded (no-GIL) build. Every
method that touches an instance's hash table now takes that instance's own
lock, two-object operations (
update(),extend(),merge(),__eq__(), copying) lock both objects in a fixed, deadlock-safe order,and the version counter shared by every instance is guarded separately. On
a regular (GIL-enabled) interpreter this adds no overhead: the locked
methods are the exact same function objects as before -- by
:user:
asvetlov.Related issues and pull requests on GitHub:
#1447.
Sped up adding many values for the same key to a
:class:
~multidict.MultiDictor :class:~multidict.CIMultiDict, eachadded value no longer gets slower than the one before it
-- by :user:
bdraco.Related issues and pull requests on GitHub:
#1466.
Improved documentation
Added the plural form "fallbacks" to the docs spell checker's allowed
word list so :file:
CHANGES.rstbuilds cleanly -- by :user:asvetlov.Related issues and pull requests on GitHub:
#1439.
Contributor-facing changes
Added race tests that iterate and extend a :class:
~multidict.MultiDictfrom several threads on a free-threaded build, so a regression in the C
extension's locking fails a free-threaded CI leg instead of going unnoticed
-- by :user:
rodrigobnogueira.Related issues and pull requests on GitHub:
#1317.
Added
AddressSanitizer/UndefinedBehaviorSanitizerandThreadSanitizerCI jobs. The former runs the suite under aregular CPython with
MULTIDICT_ASAN_BUILD=1; the latter builds afree-threaded CPython instrumented with
--with-thread-sanitizerand runs the suite against it via
MULTIDICT_TSAN_BUILD=1-- by:user:
asvetlov.Related issues and pull requests on GitHub:
#1455.
Added Hypothesis-based property and stateful fuzz tests covering
:class:
~multidict.MultiDict/:class:~multidict.CIMultiDictsemantics,views, iterators, and threaded stress scenarios, run against both the
C-extension and pure-Python backends -- by :user:
asvetlov.Related issues and pull requests on GitHub:
#1460.
Added core dump collection to the AddressSanitizer and ThreadSanitizer
CI jobs: a crash now uploads the core file alongside the crashing
interpreter binary and the compiled extension as a downloadable
artifact, for offline debugging with a matching symbol-carrying binary
instead of raw hex offsets -- by :user:
asvetlov.Related issues and pull requests on GitHub:
#1462.
Added benchmarks for adding many values for the same key and for
creating a multidict with many items -- by :user:
bdraco.Related issues and pull requests on GitHub:
#1465.
Skipped abstractmethods from coverage leaks report, they are empty placeholders that are never executed -- by :user:
asvetlovRelated issues and pull requests on GitHub:
#1470.
Add benchmarks for
__setitem__-- by :user:asvetlovRelated issues and pull requests on GitHub:
#1471.
The AddressSanitizer and ThreadSanitizer CI jobs were changed to run pytest
with
--capture=no. Previously a sanitizer abort could exit the processbefore pytest flushed its per-test output buffer, silently dropping the
sanitizer report from the job log -- by :user:
asvetlov.Related issues and pull requests on GitHub:
#1472.
Moved the
hypothesispin out ofrequirements/pytest.txtinto its ownrequirements/pytest-hypothesis.txt, installed only by the dedicatedHypothesis CI jobs.
hypothesisnow ships a Rust extension with noprebuilt wheel for some emulated architectures (e.g. musllinux i686),
which broke wheel-testing jobs that never run the Hypothesis-marked tests
in the first place -- by :user:
asvetlov.Related issues and pull requests on GitHub:
#1475.
Miscellaneous internal changes
Replaced
PyIter_Next()calls with the newerPyIter_NextItem()API inthe C extension, so the iterator-exhausted and error cases are told apart by
the return code instead of an ambiguous
NULLresult -- by :user:asvetlov.Related issues and pull requests on GitHub:
#1440.
6.9.1: 6.9.1Compare source
Source
Source ref:
masterBug fixes
Fixed the C extension reading freed memory on free-threaded builds when a
list handed to :py:meth:
~multidict.MultiDict.update,:py:meth:
~multidict.MultiDict.extend, :py:meth:~multidict.MultiDict.mergeor the :py:class:
~multidict.MultiDictand :py:class:~multidict.CIMultiDictconstructors, a
[key, value]item inside any iterable handed to them, or alist tested with
inagainst :py:meth:~multidict.MultiDict.items, ischanged by another thread; a call that catches the list shrinking under it
now raises :py:exc:
RuntimeError-- by :user:rodrigobnogueira.Related issues and pull requests on GitHub:
#1437.
Fixed a data race on the free-threaded build where a retired hash table's
reader count used relaxed atomics, letting a lock-free
get()/getone()/__getitem__()read race a concurrent free of that table. The reader-exitdecrement and the drain's free check now use release/acquire ordering
instead -- by :user:
asvetlov.Related issues and pull requests on GitHub:
#1481.
Fixed a free-threaded build bug where two threads calling
update(),merge(), or__setitem__()on the same key at the same time could losethe key entirely instead of just racing on which value wins. A decref of the
replaced value could transiently suspend the writer's critical section,
letting a second writer for the same key observe the first writer's
in-progress entry as absent and, once both settled, mistake it for a stale
duplicate and delete it. Every such decref is now deferred until the writer
has released its critical section, so the window can no longer open.
setdefault()had an unrelated instance of the same blind spot (it couldinsert a duplicate rather than recognizing an in-flight key), fixed alongside
it -- by :user:
asvetlov.Related issues and pull requests on GitHub:
#1483.
Fixed a free-threaded build bug where
getall()and theitems()/keys()/values()equality path could raiseKeyErroror report apresent, never-deleted key as missing. A concurrent
update()/extend()/__setitem__()call can have its critical section transiently suspended(a decref triggering a blocking allocator call) while an entry is marked as
part of its own bookkeeping; a reader landing in that window used to treat
the mark as "not found" instead of "still there, in flight" -- by
:user:
asvetlov.Related issues and pull requests on GitHub:
#1484.
Fixed a reference leak in the C extension where
operand | md.items()and
md.items() - operandleaked one key and one value reference perelement of
operand, letting a large operand grow memory without bound(:gh:
GHSA-54p9-h82j-f925 <aio-libs/multidict/security/advisories/GHSA-54p9-h82j-f925>)-- by :user:
asvetlov.The issue was reported by :user:
waydeshi.Related commits on GitHub:
:commit:
350b4a0.Fixed a segmentation fault on the standard (non-free-threaded) C extension
build when a value type's
__del__released the GIL (for example bycalling
time.sleep()) whileupdate(),merge(),__setitem__(),__delitem__(),pop(),popone(), orpopall()was dropping areplaced or removed value.
Py_BEGIN_CRITICAL_SECTIONcompiles to a no-opon this build, so nothing else was stopping a second thread from mutating the
very same
MultiDictconcurrently once the GIL was released mid-mutation.Every such decref is now deferred until the mutation has fully finished, the
same technique already used to close the analogous free-threaded-build race
-- by :user:
asvetlov.Related issues and pull requests on GitHub:
#1489.
Fixed the C extension reading freed memory while iterating a
:py:class:
~multidict.CIMultiDictwhose keys are plain :py:class:str.Converting such a key to :py:class:
~multidict.istrcould run Python code(a :py:class:
strsubclass's__str__or__del__) or, on free-threadedbuilds, suspend the iterator's critical section, after which the iterator read
the entry again even though a concurrent mutation could already have freed it.
As part of the fix, :py:meth:
~multidict.MultiDict.copyand re-initializingfrom another multidict now assign a new version in the C extension instead of
reusing the source's, matching the pure Python implementation
-- by :user:
asvetlov.Related issues and pull requests on GitHub:
#1496.
Fixed a use-after-free on the free-threaded build where a lock-free
get(),[]orincould read a hash table that a concurrentresize had just retired and another reader was freeing
-- by :user:
asvetlov.Related issues and pull requests on GitHub:
#1497.
Contributor-facing changes
Removed a redundant
includeand a duplicatedexcludeline fromMANIFEST.in; sdist contents are unchanged -- by :user:asvetlov.Related issues and pull requests on GitHub:
#1478.
Added
.claudeignorefile -- by :user:asvetlovRelated issues and pull requests on GitHub:
#1479.
Scaled up the pure-Python
pop(),popitem(),__delitem__(),add()and item-insertion benchmarks to do more work per measurement.Repeated CodSpeed runs on the same commit showed these particular
benchmarks flagged as dominated by syscalls, understating their real
cost and adding noise to the reported values; a larger working set
amortizes that overhead -- by :user:
asvetlov.Related issues and pull requests on GitHub:
#1485.
Replaced deprecated instrumentation codspeed mode with simulation -- by :user:
asvetlovRelated issues and pull requests on GitHub:
#1493.
Reorganized the mutating benchmarks (item insertion,
update(),add()of the same key,pop(),popitem(),clear(),__delitem__()and__setitem__()) to copy a fresh multidict andapply the operation in a loop, like the
add()andextend()benchmarks already do. The insertion,
update()andclear()benchmarks previously mutated a single multidict shared across
rounds, so only the first round measured the intended operation; the
rest did a single copy per round, letting per-round overhead dominate
-- by :user:
asvetlov.Related issues and pull requests on GitHub:
#1494.
The
repr()and view inequality benchmarks were updated to repeat theiroperation in a loop, like the other benchmarks, and the CodSpeed benchmark
job was moved to Python 3.14 -- by :user:
asvetlov.Related issues and pull requests on GitHub:
#1498.
Dropped
-Ifrom the AddressSanitizer test command inAGENTS.mdand in the CI job. It implies
-E, which made Python ignorePYTHONMALLOC=malloc, so small hash tables were still served frompymallocarenas where use-after-free went undetected-- by :user:
asvetlov.Related issues and pull requests on GitHub:
#1499.
The CI/CD workflow was updated to stop superseded runs of the same pull request
when a new commit is pushed; runs on
master, release branches, tags,the merge queue, and the daily schedule are never interrupted
-- by :user:
asvetlov.Related issues and pull requests on GitHub:
#1500.
The release job was changed to upload distributions and their signatures
to the GitHub Release one file at a time, skipping assets that were
already attached and retrying after a pause, so that a parallel upload
burst no longer tripped the GitHub secondary rate limit
-- by :user:
asvetlov.Related issues and pull requests on GitHub:
#1503.
Miscellaneous internal changes
Corrected several comments in the free-threaded C extension that
attributed critical-section suspension to a blocking
PyMem_Malloc()call; allocation alone never suspends an acquired critical section, and
the real risk at those sites is a decref running
a finalizer or weakref callback. Also dropped a retry loop in
md_clone_from_ht()that guarded against the same, non-existentallocation-triggered suspension -- by :user:
asvetlov.Related issues and pull requests on GitHub:
#1486.
Changed the free-threaded build's deferred decref buffer, used by
update()and__setitem__(), to a chain of fixed-size blockswith a large inline first block instead of a small inline array that
was reallocated on growth -- by :user:
asvetlov.Related issues and pull requests on GitHub:
#1501.
packaging (25.0 → 26.3)
26.0: 26.0Compare source
Source
Source ref:
mainRead about the performance improvements here: https://iscinumpy.dev/post/packaging-faster.
What's Changed
Features:
__replace__forVersionby @henryiii in https://github.com/pypa/packaging/pull/1003VersionandSpecifierby @henryiii in https://github.com/pypa/packaging/pull/1004Behavior adaptations:
Specifier.contains,SpecifierSet.contains, andSpecifierSet.filterby @notatallshaw in https://github.com/pypa/packaging/pull/897SpecifierSet.filterby @notatallshaw in https://github.com/pypa/packaging/pull/942SpecifierSetby @notatallshaw in https://github.com/pypa/packaging/pull/951Falseinstead of raising for.containswith invalid version by @Liam-DeVoe in https://github.com/pypa/packaging/pull/932SpecifierandSpecifierSet'sfilterandcontainsmethod. by @notatallshaw in https://github.com/pypa/packaging/pull/954Versionon certain marker keys, returnFalseon unequal ordered comparsions by @JP-Ellis in https://github.com/pypa/packaging/pull/939Fixes:
_hashwhen unpicklingTag()by @dholth in https://github.com/pypa/packaging/pull/860Specifier.prereleasesby @notatallshaw in https://github.com/pypa/packaging/pull/896_GLibCVersionNamedTuplein_manylinuxby @cthoyt in https://github.com/pypa/packaging/pull/868()by @bwoodsend in https://github.com/pypa/packaging/pull/879'name'format by @di in https://github.com/pypa/packaging/pull/925Requirementsstring by @henryiii in https://github.com/pypa/packaging/pull/953packaginglogger instead by @henryiii in https://github.com/pypa/packaging/pull/965MarkerandRequirementby @henryiii in https://github.com/pypa/packaging/pull/1022Markerfails to construct by @henryiii in https://github.com/pypa/packaging/pull/1033Performance:
_manylinux.pyby @cthoyt in https://github.com/pypa/packaging/pull/869Versionby @bearomorphism in https://github.com/pypa/packaging/pull/913Versions in specifier comparison by @notatallshaw in https://github.com/pypa/packaging/pull/986Specifier's Version by @notatallshaw in https://github.com/pypa/packaging/pull/985Versiona little faster by @henryiii in https://github.com/pypa/packaging/pull/987Versionregex cleanup by @henryiii in https://github.com/pypa/packaging/pull/990_keyinVersionby @notatallshaw in https://github.com/pypa/packaging/pull/989 and regression forpackaging_legacyfixed by @henryiii in https://github.com/pypa/packaging/pull/1048canonicalize_versionby @henryiii in https://github.com/pypa/packaging/pull/993fullmatchin a couple more places by @henryiii in https://github.com/pypa/packaging/pull/992fullmatchfor markers too by @henryiii in https://github.com/pypa/packaging/pull/1029mapinstead of generator by @henryiii in https://github.com/pypa/packaging/pull/996._version(_Version, aNamedTuple) by @henryiii in https://github.com/pypa/packaging/pull/995 and https://github.com/pypa/packaging/pull/1062Versioncreation incanonicalize_versionby @henryiii in https://github.com/pypa/packaging/pull/994__slots__toVersionby @henryiii in https://github.com/pypa/packaging/pull/1001__slots__toSpecifiers by @henryiii in https://github.com/pypa/packaging/pull/1002__slots__toNodes by @henryiii in https://github.com/pypa/packaging/pull/1032version.__replace__in specifier comparison by @notatallshaw in https://github.com/pypa/packaging/pull/999_get_spec_versionin more places inSpecifierby @notatallshaw in https://github.com/pypa/packaging/pull/1005setconstruction out of function by @henryiii in https://github.com/pypa/packaging/pull/1012Version.__str__by about 10% by @henryiii in https://github.com/pypa/packaging/pull/997canonicalize_nameby avoiding a regex by @henryiii in https://github.com/pypa/packaging/pull/1030, https://github.com/pypa/packaging/pull/1047, and https://github.com/pypa/packaging/pull/1064Type annotations:
parse_wheel_filenamedocs by @ncoghlan in https://github.com/pypa/packaging/pull/973_versionin.version.Versionby @brettcannon in https://github.com/pypa/packaging/pull/927specifier.pyby @subhajitsaha01 in https://github.com/pypa/packaging/pull/930Internal:
license-filesby @DimitriPapadopoulos in https://github.com/pypa/packaging/pull/924python_versionby @trim21 in https://github.com/pypa/packaging/pull/908ruffwas renamedruff-checkin pre-commit by @henryiii in https://github.com/pypa/packaging/pull/933log_levelis better thanlog_cli_levelby @henryiii in https://github.com/pypa/packaging/pull/956partitionin_parse_project_urlsby @henryiii in https://github.com/pypa/packaging/pull/1013packaging.licensesby @notatallshaw in https://github.com/pypa/packaging/pull/1039contextlib.contextmanagerby @SpecLad in https://github.com/pypa/packaging/pull/1046actionlintto check CI workflows by @miketheman in https://github.com/pypa/packaging/pull/1052New Contributors
Since last RC
Fixes:
._versionas a compat shim by @henryiii in https://github.com/pypa/packaging/pull/1062Performance:
Documentaiton:
Full Changelog: https://github.com/pypa/packaging/compare/26.0rc3...26.0
26.1: 26.1Compare source
Source
Source ref:
mainFeatures:
PEP 783: add handling for Emscripten wheel tags by @hoodmane in https://github.com/pypa/packaging/pull/804(old name used in implementation, will be fixed in next release)abi3.abi3tfree-threading tag by @ngoldbaum in https://github.com/pypa/packaging/pull/1099packaging.dependency_groupsmodule, based on thedependency-groupspackage by @sirosen in https://github.com/pypa/packaging/pull/1065packaging.direct_urlmodule by @sbidoul in https://github.com/pypa/packaging/pull/944packaging.errorsmodule by @henryiii in https://github.com/pypa/packaging/pull/1071SpecifierSet.is_unsatisfiableusing ranges (new internals that will be expanded in future versions) by @notatallshaw in https://github.com/pypa/packaging/pull/1119create_compatible_tags_selectorto select compatible tags by @sbidoul in https://github.com/pypa/packaging/pull/1110keyargument toSpecifierSet.filter()by @frostming in https://github.com/pypa/packaging/pull/1068&and|forMarker's by @henryiii in https://github.com/pypa/packaging/pull/1146Version.__replace__and addVersion.from_partsby @henryiii in https://github.com/pypa/packaging/pull/1078parse_wheel_filenameby @r266-tech in https://github.com/pypa/packaging/pull/1150Behavior adaptations:
<V.postNto match spec by @notatallshaw in https://github.com/pypa/packaging/pull/1140>Vto match spec by @notatallshaw in https://github.com/pypa/packaging/pull/1141format_full_versionto_format_full_versionto make it visibly private by @r266-tech in https://github.com/pypa/packaging/pull/1125Pylock (PEP 751) updates:
selectfunction by @sbidoul in https://github.com/pypa/packaging/pull/1092select()method andPylockSelectErrorby @r266-tech in https://github.com/pypa/packaging/pull/1153filenameproperty toPackageSdistandPackageWheel, more validation by @sbidoul in https://github.com/pypa/packaging/pull/1095Fixes:
>comparison for versions with dev+local segments by @veeceey in https://github.com/pypa/packaging/pull/1097InfinityTypeandNegativeInfinityTypeby @bysiber in https://github.com/pypa/packaging/pull/1093SpecifierSetby @notatallshaw in https://github.com/pypa/packaging/pull/1109keyparameter inSpecifierSet.filterwhen specifiers are empty and prerelease isFalseby @notatallshaw in https://github.com/pypa/packaging/pull/1096reproutput by @henryiii in https://github.com/pypa/packaging/pull/1090Specifier's===uses original string, not normalized, when available by @notatallshaw in https://github.com/pypa/packaging/pull/1124ValueErrorby @notatallshaw in https://github.com/pypa/packaging/pull/1155Performance:
VersiontoVersioncomparison by skipping_keyproperty by @notatallshaw in https://github.com/pypa/packaging/pull/1083Versionhash value in dedicated slot by @notatallshaw in https://github.com/pypa/packaging/pull/1118_cmpkeyto remove use of custom objects by @notatallshaw in https://github.com/pypa/packaging/pull/1116__replace__in Specifier comparison if not needed by @notatallshaw in https://github.com/pypa/packaging/pull/1081SpecifierSetusetupleinstead offrozensetfor_specsby @notatallshaw in https://github.com/pypa/packaging/pull/1108SpecifierSetfiltering by implementing cost-based ordering by @notatallshaw in https://github.com/pypa/packaging/pull/1105SpecifierSet.filterby @notatallshaw in https://github.com/pypa/packaging/pull/1076__slots__toMarkerby @henryiii in https://github.com/pypa/packaging/pull/1147Specifierregex by @sirosen in https://github.com/pypa/packaging/pull/1106Internal:
collections.namedtuplein tests by @henryiii in https://github.com/pypa/packaging/pull/1070dir()/ tab-completion in REPL by @henryiii in https://github.com/pypa/packaging/pull/1011__all__/__dir__by @henryiii in https://github.com/pypa/packaging/pull/1069SpecifierSet.prereleasesby @notatallshaw in https://github.com/pypa/packaging/pull/1073_compare_compatibleby @notatallshaw in https://github.com/pypa/packaging/pull/1100Specifier.prereleasesby @notatallshaw in https://github.com/pypa/packaging/pull/1074Specifier.prereleasesby @notatallshaw in https://github.com/pypa/packaging/pull/1072Documentation:
Version.from_parts()by @Jackenmen in https://github.com/pypa/packaging/pull/1134&and|operators for combiningMarkerobjects by @r266-tech in https://github.com/pypa/packaging/pull/1151Versiondocumentation by @henryiii in https://github.com/pypa/packaging/pull/1089Benchmarks
Performance improvements since 26.0, from the new integrated benchmark suite:
New Contributors
Full Changelog: https://github.com/pypa/packaging/compare/26.0...26.1
26.2: 26.2Compare source
Source
Source ref:
mainWhat's Changed
Fixes:
Version,Specifier,SpecifierSet,Tag,Marker, andRequirementpickle-safeand backward-compatible with pickles created in 25.0-26.1 (including references to the removed
packaging._structuresmodule) by @eachimei and @henryiii in https://github.com/pypa/packaging/pull/1163, https://github.com/pypa/packaging/pull/1168, https://github.com/pypa/packaging/pull/1170, and https://github.com/pypa/packaging/pull/1171Documentation:
Internal:
New Contributors
Full Changelog: https://github.com/pypa/packaging/compare/26.1...26.2
26.3: 26.3Compare source
Source
Source ref:
mainWhat's Changed
Features
VersionRangeAPI andSpecifierSet.to_range(), representing the versions a specifier set accepts as an interval set that supports intersection, union, difference, complement, set relations, membership tests, and filtering.VersionRange.to_specifier_set()converts a range back to aSpecifierSetwhere a PEP 440 form exists. (#1267, #1270, #1298)Metadata-Version: 2.6. (#1194)limitargument toparse_tag()for compressed tag sets. (#1220)prefer_sdist_predicateargument toPylock.select()to prefer source distributions over wheels for selected packages. (#1334)pure_python_tags()to generate the pure-Python tags for a Python version without touching the running platform. (#1346)SpecifierSet.is_subset(),SpecifierSet.is_superset(), andSpecifierSet.is_disjoint(), which compare the versions two specifier sets accept. (#1313)Behavior adaptations
linux_*platform tags overmanylinuxandmusllinuxtags on Linux. (#160)Fixes for versions and specifiers
InvalidVersioninstead ofTypeErrorwhenVersionis given a non-string. (#1319)InvalidVersionfor non-string pre-release letters passed toVersion.from_parts. (#1241)AttributeErrorwhen hashing internally trimmed versions. (#1242)SpecifierSet.is_unsatisfiablefor post-release boundary intersections. (#1257)Fixes for requirements and markers
Requirement.__hash__consistent with__eq__for trailing-zero-equivalent specifiers (e.g.foo==1.0.0andfoo==1.0.0.0), so equal requirements hash equal and deduplicate in sets and dicts. (#1232)Requirement's specifierprereleasesoverride across a pickle round trip. (#1204)InvalidRequirementinstead ofInvalidSpecifierwhen a requirement contains an invalid specifier. (#1332)==1.0.post1.*. (#1299)extraanddependency_groupsvalues in nested markers at parse time. (#1246, #1310)UndefinedComparisonwhen a set-valued variable likeextrasis used outside the membership form. (#1265)UndefinedEnvironmentName(aKeyErrorsubclass) for missing environment keys during marker evaluation. (#1276)InvalidMarker/InvalidRequirementinstead of leaking a low-level error. (#1249)Fixes for metadata and licenses
from_emailvalidation errors into oneExceptionGroupinstead of raising the first. (#1268)Description-Content-Typevalues. (#1329){field}placeholders in error messages. (#1327)unparsedinstead of asserting. (#1247)InvalidMetadataandCyclicDependencyGrouppicklable. (#1328)str.splitlinesrecognizes when writing a header withRFC822Message. (#1356)InvalidLicenseExpressionfor misplacedWITHclauses and emptyLicenseRef-names. (#1266)InvalidLicenseExpressioninstead ofKeyErrorfor aLicenseRef-with a+suffix. (#1219)Fixes for tags and filenames
InvalidTagfromparse_tag()for tags with the wrong number of components. (#1238)parse_wheel_filename()andparse_tag(). (#1234)is_normalized_namenow rejects names with collapsed double hyphens likea--b. (#1230)abi3ttags. (#1245)warnargument togeneric_tags()insys_tags(). (#1264)SystemErrorfor an empty or malformed CPythonEXT_SUFFIX. (#1271, #1301)fat3architecture name (wasfat32). (#1199)Fixes for pylock, direct URLs, and dependency groups
pylockartifact file names derived from aurlso that local versions (e.g. a wheel with2.12.1+cu130encoded as2.12.1%2Bcu130) yield a valid file name. (#1314)tagssequence inPylock.select()instead of falling back tosys_tags(). (#1349)Pylock.select()on Python builds that report a non-PEP 440python_full_version(e.g.3.15.0+). (#1179)pylockfiles. (#1244)PylockSelectErrortopackaging.pylock.__all__. (#1202)DirectUrlcredential stripping for passwords containing@. (#1218)direct_url. (#1240)direct_url. (#1297)InvalidRequirementerrors while resolving dependency groups instead of leaking them. (#1302)Performance
SpecifierandSpecifierSetfiltering with the new range engine. (#1120, #1259)_manylinuxmodule lookup process-wide. (#1254)__slots__toRequirementand the token classes. (#1320, #1258)parse_tag(), and skipplatform.mac_ver()when the version and arch are given. (#1253, #1256, #1236, #1255)Documentation
packaging.pylock. (#1339)packaging.metadatafields are validated. (#1342)RFC822Policyin the low-levelpackaging.metadatainterface. (#1222)versionadded/versionchangeddirectives and many small docstring fixes across the API reference. (#1205, #1207, #1208, #1209, #1211, #1216, #1217, #1223, #1272, #1273, #1274, #1291, #1300, #1303, #1317, #1344)Internal
New Contributors
Full Changelog: https://github.com/pypa/packaging/compare/26.2...26.3
propcache (0.4.1 → 0.5.4)
v0.5.1: 0.5.1Compare source
Source
Source ref:
masterNo significant changes.
0.5.2: 0.5.2Breaking change detected.
Compare source
Source
Source ref:
master0.5.0 and 0.5.1 were tagged earlier today but never reached PyPI: 0.5.0's deploy failed at cibuildwheel's post-build pytest on free-threaded armv7l musllinux (SIGBUS under QEMU emulation while importing the C extension), and 0.5.1's deploy hit a transient sigstore Rekor 502 during the attestation step. 0.5.2 is the first of the three to actually publish.
Features
Added support for newer type hints and remove
OptionalandUnionfrom all annotations-- by :user:
VizonexRelated issues and pull requests on GitHub:
#193.
Removals and backward incompatible breaking changes
Dropped support for Python 3.9 as it has reached end of life.
Related issues and pull requests on GitHub:
#216.
Packaging updates and notes for downstreams
Changed the Cython build dependency from
~= 3.1.0to>= 3.2.0,removing the upper version bound to avoid conflicts for downstream packagers
-- by :user:
jameshilliardand :user:gundalow.The upstream Cython version is pinned to 3.2.4 in the CI/CD environment.
Related issues and pull requests on GitHub:
#184, #188, #214.
Start building and shipping riscv64 wheels
-- by :user:
justeph.Related issues and pull requests on GitHub:
#194.
The :pep:
517build backend now supports a newbuild-inplaceconfig setting (and
PROPCACHE_BUILD_INPLACEenvironment variable)for controlling whether to build the project in-tree or in a
temporary directory. It only affects wheels and is set up to build
in a temporary directory by default. It does not affect editable
wheel builds; they will keep being built in-tree regardless.
Here's an example of using this setting:
.. code-block:: console
$ python -m build --config-setting=build-inplace=true
Additionally, when building wheels in an automatically created
temporary directory, the build backend now normalizes the
respective file system path to a deterministic source checkout
directory by injecting the
-ffile-prefix-mapcompiler optioninto the
CFLAGSenvironment variable, as suggested by knownreproducible build practices <https://reproducible-builds.org/docs/build-path/>__.The effect is that downstreams will get reproducible build results.
Related issues and pull requests on GitHub:
#218.
0.5.3: 0.5.3Breaking change detected.
Compare source
Source
Source ref:
masterBug fixes
Fixed a possible crash in the C implementation of
cached_propertyand
under_cached_propertyon free-threaded Python, where a cachedvalue could be freed by another thread while it was being read; errors
raised while looking up the cache are now propagated on all builds,
and the computed value is no longer leaked if storing it fails
-- by :user:
bdraco.Related issues and pull requests on GitHub:
#297.
Removals and backward incompatible breaking changes
Dropped support for free-threaded Python 3.13 -- by :user:
Vizonex.Related issues and pull requests on GitHub:
#223.
Improved documentation
Updated discussion links from the defunct Google Groups forum to
GitHub Discussions
-- by :user:
gundalow.Related issues and pull requests on GitHub:
#217.
Packaging updates and notes for downstreams
The
setuptoolsbuild dependency lower bound has been restored to be>= 47after an incorrect automated increase in :pr:207-- by :user:
bbhtt.Related issues and pull requests on GitHub:
#207.
Dropped support for free-threaded Python 3.13 -- by :user:
Vizonex.Related issues and pull requests on GitHub:
#223.
Dropped the deprecated
License :: OSI Approved :: Apache Software Licenseclassifier;setuptools84 warns about it and the distbuild treats warnings as errors, so releases could no longer be built
-- by :user:
bdraco.Related issues and pull requests on GitHub:
#299.
Contributor-facing changes
Dependabot has been restricted to the
requirementssubdirectory toavoid unintended updates outside dependency requirement files
-- by :user:
bbhtt.Related issues and pull requests on GitHub:
#207.
Added an
AGENTS.mdfile with contributor guidance for AIcoding agents, adapted from the
yarlequivalent-- by :user:
bdraco.Related issues and pull requests on GitHub:
#231.
Migrated from standalone
blackandisortpre-commit hooksto
ruff formatand the ruffIlint rule, sharing a new[tool.ruff]config inpyproject.toml.ruff-checkrunswith
--fixso import-order fixes apply on commit, and theorphan
[isort]block insetup.cfgwas removed-- by :user:
bdraco.Related issues and pull requests on GitHub:
#232.
Switched the
cibuildwheelbuild frontend tobuild[uv]sothat
uvprovisions every build and test virtual environmentin the wheel matrix. Test-dependency installation in particular
drops from a multi-second
pip installper ABI to a roughlysub-second
uvresolve-- by :user:
bdraco.Related issues and pull requests on GitHub:
#234.
Dropped the
libffi-develinstall from thecibuildwheelLinux
before-allstep. It was added in :pr:75socfficould build from source during wheel testing; thecurrent wheel-test chain no longer pulls in
cffi, so theheader package is dead weight
-- by :user:
bdraco.Related issues and pull requests on GitHub:
#236.
The type preciseness coverage report generated by
MyPy <https://mypy-lang.org>__ is now uploaded toCoveralls <https://coveralls.io/github/aio-libs/propcache>__ andwill not be included in the
Codecov views <https://app.codecov.io/gh/aio-libs/propcache>__ going forward-- by :user:
aiolibsbot.Related issues and pull requests on GitHub:
#239.
Switched CI/CD to
tox-dev/workflow's :file:reusable-tox.ymldriven by an in-tree :file:
tox.ini. Thebuild,metadata-validationandlint(pre-commit,spellcheck-docs) jobs all run through the reusable workflow;mypycoverage uploads to Coveralls from apost-tox-jobhook
-- by :user:
bdraco.Related issues and pull requests on GitHub:
#243.
Overrode
CIBW_BUILD_FRONTEND=buildfor the QEMU-emulatedodd-arch wheel matrix, since the pypa odd-arch container images
do not ship
uvpreinstalled and the project's:file:
pyproject.tomlsetsbuild-frontend = "build[uv]"-- by :user:
bdraco.Related issues and pull requests on GitHub:
#246.
Allowed re-running the deploy job after a partial release failure: the
Make Releasestep now skips when the GitHub Release already exists,and the PyPI publish step uses
skip-existingso dists that werealready uploaded on a prior attempt do not break the retry
-- by :user:
bdraco.Related issues and pull requests on GitHub:
#247.
Switched the aarch64 and armv7l wheel builds to GitHub's native ARM
runners. The aarch64 wheels now build without QEMU emulation, and
armv7l runs on aarch64 hosts so its 32-bit ARM execution is far
cheaper than the previous aarch64-on-x86_64 path
-- by :user:
bdraco.Related issues and pull requests on GitHub:
#248.
Added
UV_CONSTRAINTandUV_BUILD_CONSTRAINTalongsidePIP_CONSTRAINTandPIP_BUILD_CONSTRAINTin thecibuildwheelenvironment so the :file:requirements/cython.txtpin is honored under the
build[uv]frontend;uv pipignores the
PIP_variables and reads only theUV_ones,while the
PIP_variants are kept for the pip fallback path-- by :user:
bdraco.Related issues and pull requests on GitHub:
#249.
Fixed coverage for testing benchmarks when codspeed is not installed
-- by :user:
Vizonex.Related issues and pull requests on GitHub:
#251.
Stopped running the test suite inside the wheel build jobs outside of
release builds, since the test matrix installs and tests the same
wheels, and added Python 3.15 and 3.15t to the test matrix so those
wheels stay covered. Off-tag macOS builds are now limited to the
architecture the test matrix runs on. Release builds still build every
architecture and test every wheel, and all release checks in the CI
workflow now use
github.ref_type-- by :user:
bdraco.Related issues and pull requests on GitHub:
#300.
0.5.4: 0.5.4Compare source
Source
Source ref:
masterPackaging updates and notes for downstreams
Fixed the release wheels being compiled without optimization since
version 0.5.0. The build backend set
CFLAGSto add-ffile-prefix-map, which replaced the interpreter's own compilerflags instead of extending them, so
-O3and-DNDEBUGweredropped; the extra flags now go through
CPPFLAGS, which isappended. Cached property reads are about 1.5x faster than in 0.5.3
-- by :user:
bdraco.Related issues and pull requests on GitHub:
#244, #302.
pygments (2.19.2 → 2.21.0)
2.20.0: 2.20.0Compare source
Source
Source ref:
masterNew lexers:
Updated lexers:
analyse_text(#3028, #3032)]',]?,]!(#2946)__PROPERTY__magic constant (#2924), add reserved keywords (#3002)t-string support (#2973, #3009, #3010).xbrlas file ending (#2890, #2891)Drop Python 3.8, and add Python 3.14 as a supported version (#2987, #3012)
Various improvements to
autopygmentize(#2894)Update
onedarkstyle to support more token types (#2977)Update
rttstyle to support more token types (#2895)Cache entry points to improve performance (#2979)
Fix
xterm-256color table (#3043)Fix
kwargsdictionary getting mutated on each call (#3044)2.21.0: 2.21.0Compare source
Source
Source ref:
masterNew lexers:
Updated lexers:
$@or@$prefixes (#2685)
union(#3182).ippas a file extension (#3141, #1008)\spaceand\o377as a single token (#979)constructs such as
template,classandnamespace(#3127)SET(#3167)argumentsobject (#3146)?) consume the followingcharacter, so
Foo?,anda?:btokenize correctly (#2964)***...***and___...___) (#3067)embedded code blocks (#3133)
\[Name]named-character escapes such as\[Nu]instead of emitting anErrortoken (#3097)...line continuations in functiondefinition signatures (#659)
SET(#3110)sentinel(#3114)frozendict(#3119).and+in directive/role names (#3085)<<after),]or}as the shift operatorrather than the start of a heredoc (#760)
funca keyword inclass functype methods (#1125)$namevariable references at a dash (#1720)moduleas a keyword when followed bywhitespace, so identifiers like
modulesandmodule.exportsare highlighted correctly (#2823)
ymlalias (#3169), recognize non-breaking spaces as validscalar content (#2827)
New styles:
Fix catastrophic backtracking in
looks_like_xml(#2931, #3112)Improve monokai theme colors (#3100)
Improve handling of non-string types in
html_escapeto fix broken clients (#3090, #3086)LaTeX formatter: honor the wrapped lexer's
stripnland other inputoptions when
escapeinsideis set, so blank lines are no longer strippedunder
stripnl=false(#2975)RawTokenFormatter: fix a crash when
error_coloris set (#3215)Groff formatter: don't duplicate a character when word-wrapping (
wrap)a token that is not at the end of a line (#3201)
Add support for Python 3.15 (#3099)
Fix invalid
-Lvalues report success (#3217)Allow
transparentas a color style definition (#3180, #3170)HtmlFormatter:
"and'now render literally (#3185)pyrefly (1.2.0 → 1.3.1)
1.2.11.3.01.3.1ruff (0.14.11 → 0.16.9)
0.14.120.14.13: 0.14.13Compare source
Source
Release Notes
Released on 2026-01-15.
This is a follow-up release to 0.14.12. Because of an issue publishing the WASM packages, there is no GitHub release or Git tag for 0.14.12, although the package was published to PyPI. The contents of the 0.14.13 release are identical to 0.14.12.
0.14.12
Preview features
flake8-blind-except] Allow more logging methods (BLE001) (#22057)ruff] Respectlint.pydocstyle.property-decoratorsinRUF066(#22515)Bug fixes
--show-settings(#22478)fmt: skipfor multiple statements on the same logical line (#22119)Rule changes
pydocstyle] Update Rust crate imperative to v1.0.7 (D401) (#22519)isort] Insert imports in alphabetical order (I002) (#22493)Documentation
flake8-pytest-style] Addcheckparameter example toPT017docs (#22546)ruff] Make example error out-of-the-box (RUF103) (#22558)ruff] documentRUF100trailing comment fix behavior (#22479)Other changes
Contributors
Install ruff 0.14.13
Install prebuilt binaries via shell script
Install prebuilt binaries via powershell script
Download ruff 0.14.13
0.14.14: 0.14.14Compare source
Source
Release Notes
Released on 2026-01-22.
Preview features
airflow] Second positional argument toAsset/Datasetshould not be a dictionary (AIR303) (#22453)ruff] Detect duplicate entries in__all__(RUF068) (#22114)Bug fixes
pyupgrade] Allow shadowing non-builtin bindings (UP029) (#22749)pyupgrade] ApplyUP045to string arguments oftyping.cast(#22320)flake8-pie] Detect duplicated declared class fields inPIE794(#22717)Rule changes
flake8-pyi] Fix inconsistent handling of forward references for__new__,__enter__,__aenter__inPYI034(#22798)flake8-pytest-style] Supportcheckparameter inPT011(#22725)ruff] Add exception forctypes.Structure._fields_(RUF012) (#22559)flake8-bugbear]B009,B010,B013,B014,B033flake8-simplify]SIM910,SIM911pyupgrade]UP007,UP039,UP041,UP045refurb]FURB105,FURB116,FURB136,FURB140,FURB145,FURB154,FURB157,FURB164,FURB181,FURB188ruff]RUF019,RUF020Documentation
--exit-non-zero-on-formatto formatter exit codes section (#22761)FastAPI] Document fix safety forFAST001(#22655)flake8-async] Tweak explanation to focus on latency/efficiency tradeoff (ASYNC110) (#22715)pandas-vet] Make example error out-of-the-box (PD002) (#22561)refurb] Make the example work out of box (FURB101) (#22770)refurb] Make the example work out of box (FURB103) (#22769)Contributors
Install ruff 0.14.14
Install prebuilt binaries via shell script
Install prebuilt binaries via powershell script
Download ruff 0.14.14
0.15.0: 0.15.0Breaking change detected.
Compare source
Source
Release Notes
Released on 2026-02-03.
Check out the blog post for a migration guide and overview of the changes!
Breaking changes
Ruff now formats your code according to the 2026 style guide. See the formatter section below or in the blog post for a detailed list of changes.
The linter now supports block suppression comments. For example, to suppress
N803for all parameters in this function:See the documentation for more details.
The
ruff:alpineDocker image is now based on Alpine 3.23 (up from 3.21).The
ruff:debianandruff:debian-slimDocker images are now based on Debian 13 "Trixie" instead of Debian 12 "Bookworm."Binaries for the
ppc64(64-bit big-endian PowerPC) architecture are no longer included in our releases. It should still be possible to build Ruff manually for this platform, if needed.Ruff now resolves all
extended configuration files before falling back on a default Python version.Stabilization
The following rules have been stabilized and are no longer in preview:
blocking-http-call-httpx-in-async-function(ASYNC212)blocking-path-method-in-async-function(ASYNC240)blocking-input-in-async-function(ASYNC250)map-without-explicit-strict(B912)if-exp-instead-of-or-operator(FURB110)single-item-membership-test(FURB171)missing-maxsplit-arg(PLC0207)unnecessary-lambda(PLW0108)unnecessary-empty-iterable-within-deque-call(RUF037)in-empty-collection(RUF060)legacy-form-pytest-raises(RUF061)non-octal-permissions(RUF064)invalid-rule-code(RUF102)invalid-suppression-comment(RUF103)unmatched-suppression-comment(RUF104)replace-str-enum(UP042)The following behaviors have been stabilized:
--output-formatflag is now respected when running Ruff in--watchmode, and thefulloutput format is now used by default, matching the regular CLI output.builtin-attribute-shadowing(A003) now detects the use of shadowed built-in names in additional contexts like decorators, default arguments, and other attribute definitions.duplicate-union-member(PYI016) now considerstyping.Optionalwhen searching for duplicate union members.split-static-string(SIM905) now offers an autofix when themaxsplitargument is provided, even without asepargument.dict-get-with-none-default(SIM910) now applies to more types of key expressions.super-call-with-parameters(UP008) now has a safe fix when it will not delete comments.unnecessary-default-type-args(UP043) now applies to stub (.pyi) files on Python versions before 3.13.Formatter
This release introduces the new 2026 style guide, with the following changes:
exceptclauses will now be removed on Python 3.14 and later (#20768)ascaptures inmatchstatements (#21176)Preview features
Apply formatting to Markdown code blocks (#22470, #22990, #22996)
See the documentation for more details.
Bug fixes
Rule changes
fix_titlesub-diagnostic appears (#23044)FastAPI] Add sub-diagnostic explaining why a fix was unavailable (FAST002) (#22565)flake8-annotations] Don't suggestNoReturnfor functions raisingNotImplementedError(ANN201,ANN202,ANN205,ANN206) (#21311)pyupgrade] Make fix unsafe if it deletes comments (UP017) (#22873)pyupgrade] Make fix unsafe if it deletes comments (UP020) (#22872)pyupgrade] Make fix unsafe if it deletes comments (UP033) (#22871)refurb] Do not addabc.ABCif already present (FURB180) (#22234)refurb] Make fix unsafe if it deletes comments (FURB110) (#22768)ruff] Add sub-diagnostics with permissions (RUF064) (#22972)Server
didOpeninstead of.ipynbfile extension (#22810)CLI
--colorCLI option to force colored output (#22806)Documentation
-stdin convention in CLI help text (#22817)refurb] Change example tore.searchwith^anchor (FURB167) (#22984)pydocstyle] Clarify which quote styles are allowed (D300) (#22825)flake8-bugbear] Improve docs forno-explicit-stacklevel(B028) (#22538)Other changes
Contributors
Install ruff 0.15.0
Install prebuilt binaries via shell script
Install prebuilt binaries via powershell script
Download ruff 0.15.0
0.15.1: 0.15.1Compare source
Source
Release Notes
Released on 2026-02-12.
Preview features
airflow] Add ruff rules to catch deprecated Airflow imports for Airflow 3.1 (AIR321) (#22376)airflow] Third positional parameter not namedti_keyshould be flagged forBaseOperatorLink.get_link(AIR303) (#22828)flake8-gettext] Fix false negatives for plural argument ofngettext(INT001,INT002,INT003) (#21078)pyflakes] Fix infinite loop in preview fix forunused-import(F401) (#23038)pygrep-hooks] Detect non-existent mock methods in standalone expressions (PGH005) (#22830)pylint] Allow dunder submodules and improve diagnostic range (PLC2701) (#22804)pyupgrade] Improve diagnostic range for tuples (UP024) (#23013)refurb] Check subscripts in tuple do not use lambda parameters inreimplemented-operator(FURB118) (#23079)ruff] Detect mutable defaults infieldcalls (RUF008) (#23046)ruff] Ignore stdcmath.inf(RUF069) (#23120)ruff] New rulefloat-equality-comparison(RUF069) (#20585)pyconMarkdown code blocks (#23112)Bug fixes
FAST001(#23224)FAST003autofix (#23227)InitVarfor__post_init__that references PEP 695 type parameters (#23226)RUF020target for multiline fixes (#23210)UP007target for multiline fixes (#23208)pyupgrade] Fix syntax error on string with newline escape and comment (UP037) (#22968)Rule changes
ruffinstead ofRuffas the program name in GitHub output format (#23240)PT006] Fix syntax error when unpacking nested tuples inparametrizefixes (#22441) (#22464)airflow] Catch deprecated attribute access from context key for Airflow 3.0 (AIR301) (#22850)airflow] Capture deprecated arguments and a decorator (AIR301) (#23170)flake8-boolean-trap] Addmultiprocessing.Valueto excluded functions forFBT003(#23010)flake8-bugbear] Add a secondary annotation showing the previous occurrence (B033) (#22634)flake8-type-checking] Add sub-diagnostic showing the runtime use of an annotation (TC004) (#23091)isort] Support configurable import section heading comments (#23151)ruff] Improve the diagnostic forRUF012(#23202)Formatter
format --check --silent(#17736)Documentation
runtime-evaluated-decoratorsexample (#23187)Other changes
Contributors
Install ruff 0.15.1
Install prebuilt binaries via shell script
Install prebuilt binaries via powershell script
Download ruff 0.15.1
0.15.2: 0.15.2Compare source
Source
Release Notes
Released on 2026-02-19.
Preview features
Expand the default rule set (#23385)
In preview, Ruff now enables a significantly expanded default rule set of 412 rules, up from the stable default set of 59 rules. The new rules are mostly a superset of the stable defaults, with the exception of these rules, which are removed from the preview defaults:
multiple-imports-on-one-line(E401)module-import-not-at-top-of-file(E402)module-import-not-at-top-of-file(E701)multiple-statements-on-one-line-semicolon(E702)useless-semicolon(E703)none-comparison(E711)true-false-comparison(E712)not-in-test(E713)not-is-test(E714)type-comparison(E721)lambda-assignment(E731)ambiguous-variable-name(E741)ambiguous-class-name(E742)ambiguous-function-name(E743)undefined-local-with-import-star(F403)undefined-local-with-import-star-usage(F405)undefined-local-with-nested-import-star-usage(F406)forward-annotation-syntax-error(F722)If you use preview and prefer the old defaults, you can restore them with configuration like:
If you do give them a try, feel free to share your feedback in the GitHub discussion!
[
flake8-pyi] Also check string annotations (PYI041) (#19023)Bug fixes
flake8-async] Fixin_async_contextlogic (#23426)ruff] Fix forRUF102should delete entire comment (#23380)ruff] Suppress diagnostic for strings with backslashes in interpolations before Python 3.12 (RUF027) (#21069)flake8-bugbear] FixB023false positive for immediately-invoked lambdas (#23294)Rule changes
flake8-executable] Allow global flags in uv shebangs (EXE003) (#22582)pyupgrade] Fix handling oftyping.{io,re}(UP035) (#23131)ruff] DetectPLC0207on chainedstr.split()calls (#23275)CLI
noqawarning (#23270)Configuration
Documentation
Q004to the list of conflicting rules (#23340)ruff] Expandlint.externaldocs and add sub-diagnostic (RUF100,RUF102) (#23268)Contributors
Install ruff 0.15.2
Install prebuilt binaries via shell script
Install prebuilt binaries via powershell script
Download ruff 0.15.2
Verifying GitHub Artifact Attestations
The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
You can also download the attestation from GitHub and verify against that directly:
0.15.3: 0.15.3Compare source
Source
Release Notes
Released on 2026-02-26.
Preview features
Drop explicit support for
.qmdfile extension (#23572)This can now be enabled instead by setting the
extensionoption:Include configured extensions in file discovery (#23400)
[
flake8-bandit] Allow suspicious imports inTYPE_CHECKINGblocks (S401-S415) (#23441)[
flake8-bugbear] AllowB901in pytest hook wrappers (#21931)[
flake8-import-conventions] Add missing conventions from upstream (ICN001,ICN002) (#21373)[
pydocstyle] Add rule to enforce docstring section ordering (D420) (#23537)[
pylint] Implementswap-with-temporary-variable(PLR1712) (#22205)[
ruff] Addunnecessary-assign-before-yield(RUF070) (#23300)[
ruff] Support file-level noqa inRUF102(#23535)[
ruff] Suppress diagnostic for invalid f-strings before Python 3.12 (RUF027) (#23480)[
flake8-bandit] Don't flagBaseLoader/CBaseLoaderas unsafe (S506) (#23510)Bug fixes
I002andPYI025(#23352)pyflakes] Fix false positive for@overloadfromlint.typing-modules(F811) (#23357)pyupgrade] Fix false positive forTypeVardefault before Python 3.12 (UP046) (#23540)pyupgrade] Fix handling of\Nin raw strings (UP032) (#22149)Rule changes
Render sub-diagnostics in the GitHub output format (#23455)
[
flake8-bugbear] Tag certainB007diagnostics as unnecessary (#23453)[
ruff] Ignore unknown rule codes inRUF100(#23531)These are now flagged by
RUF102instead.Documentation
pydocstyle] Fix double comma in description ofD404(#23440)Other changes
find_ruff_bin) for parity with uv (#23406)Contributors
Install ruff 0.15.3
Install prebuilt binaries via shell script
Install prebuilt binaries via powershell script
Download ruff 0.15.3
Verifying GitHub Artifact Attestations
The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
You can also download the attestation from GitHub and verify against that directly:
0.15.4: 0.15.4Compare source
Source
Release Notes
Released on 2026-02-26.
This is a follow-up release to 0.15.3 that resolves a panic when the new rule
PLR1712was enabled with any rule that analyzes definitions, such as many of theANNorDrules.Bug fixes
pyflakes] Suppress false positive inF821for names used beforedelin stub files (#23550)Documentation
import-headingexample (#23568)Contributors
Install ruff 0.15.4
Install prebuilt binaries via shell script
Install prebuilt binaries via powershell script
Download ruff 0.15.4
Verifying GitHub Artifact Attestations
The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
You can also download the attestation from GitHub and verify against that directly:
0.15.5: 0.15.5Compare source
Source
Release Notes
Released on 2026-03-05.
Preview features
perflint] ExtendPERF102to comprehensions and generators (#23473)refurb] FixFURB101andFURB103false positives when I/O variable is used later (#23542)ruff] Add fix fornone-not-at-end-of-union(RUF036) (#22829)ruff] Fix false positive forre.splitwith empty string pattern (RUF055) (#23634)Bug fixes
fastapi] Handle callable class dependencies with__call__method (FAST003) (#23553)pydocstyle] Fix numpy section ordering (D420) (#23685)pyflakes] Fix false positive for names shadowing re-exports (F811) (#23356)pyupgrade] Avoid inserting redundantNoneelements inUP045(#23459)Documentation
Other changes
Contributors
Install ruff 0.15.5
Install prebuilt binaries via shell script
Install prebuilt binaries via powershell script
Download ruff 0.15.5
Verifying GitHub Artifact Attestations
The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
You can also download the attestation from GitHub and verify against that directly:
0.15.6: 0.15.6Compare source
Source
Release Notes
Released on 2026-03-12.
Preview features
lazyimport parsing (#23755)airflow] FlagVariable.get()calls outside of task execution context (AIR003) (#23584)airflow] Flag runtime-varying values in DAG/task constructor arguments (AIR304) (#23631)flake8-bugbear] Implementdelattr-with-constant(B043) (#23737)flake8-tidy-imports] AddTID254to enforce lazy imports (#23777)flake8-tidy-imports] Allow users to ban lazy imports withTID254(#23847)isort] Retainlazykeyword when sorting imports (#23762)pyupgrade] Addfrom __future__ import annotationsautomatically (UP006) (#23260)refurb] Supportnewlineparameter inFURB101for Python 3.13+ (#23754)ruff] Addos-path-commonprefix(RUF071) (#23814)ruff] Add unsafe fix for os-path-commonprefix (RUF071) (#23852)ruff] LimitRUF036to typing contexts; make it unsafe for non-typing-only (#23765)ruff] Use starred unpacking forRUF017in Python 3.15+ (#23789)Bug fixes
--add-noqacreating unwanted leading whitespace (#23773)--add-noqabreaking shebangs (#23577)flake8-annotations] Fix stack overflow inANN401on quoted annotations with escape sequences (#23912)pep8-naming] Check naming conventions inmatchpattern bindings (N806,N815,N816) (#23899)perflint] Fix comment duplication in fixes (PERF401,PERF403) (#23729)pyupgrade] Properly triggersuperchange in nested class (UP008) (#22677)ruff] Avoid syntax errors inRUF036fixes (#23764)Rule changes
flake8-bandit] FlagS501withrequests.request(#23873)flake8-executable] Fix WSL detection in non-Docker containers (#22879)flake8-print] Ignorepprintcalls withstream=(#23787)Documentation
flake8-bugbear] Fix misleading description forB904(#23731)Contributors
Install ruff 0.15.6
Install prebuilt binaries via shell script
Install prebuilt binaries via powershell script
Download ruff 0.15.6
Verifying GitHub Artifact Attestations
The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
You can also download the attestation from GitHub and verify against that directly:
0.15.7: 0.15.7Compare source
Source
Release Notes
Released on 2026-03-19.
Preview features
noqahover for non-Python documents (#24040)Rule changes
pycodestyle] Recognizepyrefly:as a pragma comment (E501) (#24019)Server
Documentation
pylint] Improve phrasing (PLC0208) (#24033)Other changes
Contributors
Install ruff 0.15.7
Install prebuilt binaries via shell script
Install prebuilt binaries via powershell script
Download ruff 0.15.7
Verifying GitHub Artifact Attestations
The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
You can also download the attestation from GitHub and verify against that directly:
0.15.8: 0.15.8Compare source
Source
Release Notes
Released on 2026-03-26.
Preview features
ruff] New ruleunnecessary-if(RUF050) (#24114)ruff] New ruleuseless-finally(RUF072) (#24165)ruff] New rulef-string-percent-format(RUF073): warn when using%operator on an f-string (#24162)pyflakes] Recognizefrozendictas a builtin for Python 3.15+ (#24100)Bug fixes
flake8-async] Use fully-qualifiedanyio.lowlevelimport in autofix (ASYNC115) (#24166)flake8-bandit] Check tuple arguments for partial paths inS607(#24080)pyflakes] Skipundefined-name(F821) for conditionally deleted variables (#24088)E501/W505/formatter: Exclude nested pragma comments from line width calculation (#24071)%foo?parsing in IPython assignment expressions (#24152)analyze graph: resolve string imports that reference attributes, not just modules (#24058)Rule changes
eradicate] ignorety: ignorecomments inERA001(#24192)flake8-bandit] Treatsys.executableas trusted input inS603(#24106)flake8-self] RecognizeSelfannotation andselfassignment inSLF001(#24144)pyflakes]F507: Fix false negative for non-tuple RHS in%-formatting (#24142)refurb] Parenthesize generator arguments inFURB142fixer (#24200)Performance
Server
Documentation
extend-ignoreandextend-selectsettings documentation (#24064)Other changes
Contributors
Install ruff 0.15.8
Install prebuilt binaries via shell script
Install prebuilt binaries via powershell script
Download ruff 0.15.8
Verifying GitHub Artifact Attestations
The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
You can also download the attestation from GitHub and verify against that directly:
0.15.9: 0.15.9Compare source
Source
Release Notes
Released on 2026-04-02.
Preview features
pyflakes] Flag annotated variable redeclarations asF811in preview mode (#24244)ruff] Allow dunder-named assignments in non-strict mode forRUF067(#24089)Bug fixes
flake8-errmsg] Avoid shadowing existingmsgin fix forEM101(#24363)flake8-simplify] Ignore pre-initialization references inSIM113(#24235)pycodestyle] FixW391fixes for consecutive empty notebook cells (#24236)pyupgrade] FixUP008nested class matching (#24273)pyupgrade] Ignore strings with string-only escapes (UP012) (#16058)ruff]RUF072: skip formfeeds on dedent (#24308)ruff] Avoid re-using symbol inRUF024fix (#24316)ruff] Parenthesize expression inRUF050fix (#24234)Rule changes
flake8-simplify] SuppressSIM105forexcept*before Python 3.12 (#23869)pyflakes] ExtendF507to flag%-format strings with zero placeholders (#24215)pyupgrade]UP018should detect more unnecessarily wrapped literals (UP018) (#24093)pyupgrade] FixUP008callable scope handling to support lambdas (#24274)ruff]RUF010: Mark fix as unsafe when it deletes a comment (#24270)Formatter
nested-string-quote-styleformatting option (#24312)Documentation
flake8-bugbear] Clarify RUF071 fix safety for non-path string comparisons (#24149)flake8-type-checking] Clarify import cycle wording forTC001/TC002/TC003(#24322)Other changes
|(#24343)Contributors
Install ruff 0.15.9
Install prebuilt binaries via shell script
Install prebuilt binaries via powershell script
Download ruff 0.15.9
Verifying GitHub Artifact Attestations
The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
You can also download the attestation from GitHub and verify against that directly:
0.15.10: 0.15.10Compare source
Source
Release Notes
Released on 2026-04-09.
Preview features
flake8-logging] Allow closures in except handlers (LOG004) (#24464)flake8-self] MakeSLFdiagnostics robust to non-self-named variables (#24281)flake8-simplify] Make the fix forcollapsible-ifsafe inpreview(SIM102) (#24371)Bug fixes
E502fixes in f-strings and t-strings (#24410)dedent_to(#24381)pyupgrade] Fix panic caused by handling of octals (UP012) (#24390)Rule changes
ruff] Treat f-string interpolation as potential side effect (RUF019) (#24426)Server
Documentation
Contributors
Install ruff 0.15.10
Install prebuilt binaries via shell script
Install prebuilt binaries via powershell script
Download ruff 0.15.10
Verifying GitHub Artifact Attestations
The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
You can also download the attestation from GitHub and verify against that directly:
0.15.11: 0.15.11Compare source
Source
Release Notes
Released on 2026-04-16.
Preview features
ruff] IgnoreRUF029when function is decorated withasynccontextmanager(#24642)airflow] Implementairflow-xcom-pull-in-template-string(AIR201) (#23583)flake8-bandit] FixS103false positives and negatives in mask analysis (#24424)Bug fixes
flake8-async] Omit overridden methods forASYNC109(#24648)Documentation
flake8-async] Add override mention toASYNC109docs (#24666)vim.lsp.config(#24577)Contributors
Install ruff 0.15.11
Install prebuilt binaries via shell script
Install prebuilt binaries via powershell script
Download ruff 0.15.11
Verifying GitHub Artifact Attestations
The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
You can also download the attestation from GitHub and verify against that directly:
0.15.12: 0.15.12Compare source
Source
Release Notes
Released on 2026-04-24.
Preview features
#ruff:file-ignorefile-level suppressions (#23599)#ruff:ignorelogical-line suppressions (#23404)airflow] Implementtask-branch-as-short-circuit(AIR004) (#23579)flake8-bugbear] Fixbreak/continuehandling inloop-iterator-mutation(B909) (#24440)pylint] FixPLC2701for type parameter scopes (#24576)Rule changes
pandas-vet] Suggest.arrayas well inPD011(#24805)CLI
Documentation
pylint] FixPLR0124description not to claim self-comparison always returns the same value (#24749)pyupgrade] Expand docs on reusableTypeVars and scoping (UP046) (#24153)Contributors
Install ruff 0.15.12
Install prebuilt binaries via shell script
Install prebuilt binaries via powershell script
Download ruff 0.15.12
Verifying GitHub Artifact Attestations
The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
You can also download the attestation from GitHub and verify against that directly:
0.15.13: 0.15.13Compare source
Source
Release Notes
Released on 2026-05-14.
Preview features
pylint] Standardize diagnostic message (PLR0914,PLR0917) (#24996)Bug fixes
F811false positive for class methods (#24933)eradicate] Fix false positive for lines with leading whitespace (ERA001) (#25122)flake8-pyi] Fix false positive for f-string debug specifier (PYI016) (#24098)Rule changes
PYI034for in-place operations to enclosing class (#24511)global(#24902)Performance
isort] Avoid constructingglob::Patterns for literal known modules (#25123)CLI
--confighelp text (#25013)Configuration
line-lengthsetting (#24962)Documentation
D203to rules that conflict with the formatter (#25044)COM819and formatter interaction (#25045)NotImplementedis a value, not an exception (F901) (#25054)Other changes
Contributors
Install ruff 0.15.13
Install prebuilt binaries via shell script
Install prebuilt binaries via powershell script
Download ruff 0.15.13
Verifying GitHub Artifact Attestations
The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
You can also download the attestation from GitHub and verify against that directly:
0.15.14: 0.15.14Compare source
Source
Release Notes
Released on 2026-05-21.
Preview features
airflow] Implementairflow-task-implicit-multiple-outputs(AIR202) (#25152)flake8-use-pathlib] MarkPTH101fix as unsafe when first argument is a class attribute annotated asint(#25086)pylint] Implementtoo-many-try-statements(W0717) (#23970)ruff] Addincorrect-decorator-order(RUF074) (#23461)ruff] Addfallible-context-manager(RUF075) (#22844)Bug fixes
frozensetannotations as immutable (#25251)flake8-type-checking] Avoidstrictbehavior whenfuture-annotationsare enabled (TC001,TC002,TC003) (#25035)pylint] Avoid false positives inelseclause (PLR1733) (#25177)Rule changes
flake8-comprehensions] SkipC417for lambdas with positional-only parameters (#25272)flake8-simplify] Preserve f-string source verbatim inSIM101fix (#25061)Performance
Documentation
Other changes
ruff_python_stdlibAPIs (#25273)Contributors
Install ruff 0.15.14
Install prebuilt binaries via shell script
Install prebuilt binaries via powershell script
Download ruff 0.15.14
Verifying GitHub Artifact Attestations
The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
You can also download the attestation from GitHub and verify against that directly:
0.15.15: 0.15.15Compare source
Source
Release Notes
Released on 2026-05-28.
Preview features
pyflakes] Report duplicate imports intyping.TYPE_CHECKINGblock (F811) (#22560)Bug fixes
pyflakes] Treat function-scope bare annotations as locals per PEP 526 (F821) (#21540)Performance
TokenValuedrops in the lexer (#25300)Vecsize (#25354)ThinVecin AST to shrinkStmt(#25361)Documentation
line-lengthexample for--configoption (#25389)flake8-comprehensions] DocumentRecursionErroredge case in__len__(C416) (#25286)mccabe] Improve example (C901) (#25287)pyupgrade] Clarify fix safety docs (UP007,UP045) (#25288)refurb] DocumentFURB192exception change for empty sequences (#25317)ruff] Document false negative for user-defined types (RUF013) (#25289)Formatter
Server
codeAction/resolverequests that contain no or no valid URL (#25365)Other changes
Contributors
Install ruff 0.15.15
Install prebuilt binaries via shell script
Install prebuilt binaries via powershell script
Download ruff 0.15.15
Verifying GitHub Artifact Attestations
The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
You can also download the attestation from GitHub and verify against that directly:
0.15.16: 0.15.16Compare source
Source
Release Notes
Released on 2026-06-04.
Preview features
flake8-async] Implementyield-in-context-manager-in-async-generator(ASYNC119) (#24644)pylint] Narrow diagnostic range and exclude cases without exception handlers (PLW0717) (#25440)ruff] Treatyieldbeforebreakfrom a terminal loop as terminal (RUF075) (#25447)Bug fixes
eradicate] Avoid flaggingruff:ignorecomments as code (ERA001) (#25537)eradicate] FixERA001/RUF100conflict whennoqais on commented-out code (#25414)pyflakes] Avoid removing theformatcall when it would change behavior (F523) (#25320)pylint] Avoid syntax errors in invalid character replacements in f-strings before Python 3.12 (PLE2510,PLE2512,PLE2513,PLE2514,PLE2515) (#25544)pyupgrade] Avoid convertingformatcalls with more kinds of side effects (UP032) (#25484)Rule changes
flake8-pytest-style] Avoid fixes for ambiguousargnamesandargvaluescombinations (PT006) (#24776)Performance
Documentation
pydocstyle] Improve discoverability of rules enabled for each convention (#24973)ruff] Restore example code for Python versions before 3.15 (RUF017) (#25439)bin/active→bin/activatein tutorial (#25473)Other changes
Contributors
Install ruff 0.15.16
Install prebuilt binaries via shell script
Install prebuilt binaries via powershell script
Download ruff 0.15.16
Verifying GitHub Artifact Attestations
The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
You can also download the attestation from GitHub and verify against that directly:
0.15.17: 0.15.17Compare source
Source
Release Notes
Released on 2026-06-11.
Preview features
ignorecomments within adisable/enablepair (#25845)ruff:ignoresuppressions (#25673)flake8-async] Addtrio.as_safe_channelto safe decorators (ASYNC119) (#25775)flake8-pytest-style] Also checkpytest_asynciofixtures (#25375)ruff] Banpytestautouse fixtures (RUF076) (#25477)pyupgrade] Addfrom __future__ import annotationsautomatically (UP007,UP045) (#23259)Bug fixes
ruff:enableorruff:disableappears whereruff:ignoreis expected (#25700)pyupgrade] Preserve leading empty literals to avoid syntax errors (UP032) (#25491)Rule changes
flake8-pytest-style] Clarify diagnostic message for single parameters (PT007) (#25592)numpy] Drop autofix fornp.in1d(NPY201) (#25612)pylint] Exempt Python version comparisons (PLR2004) (#25743)Performance
Vecs with correct capacity for common cases (#25451)Formatter
CLI
ruff rule(#25640)Other changes
Contributors
Install ruff 0.15.17
Install prebuilt binaries via shell script
Install prebuilt binaries via powershell script
Download ruff 0.15.17
Verifying GitHub Artifact Attestations
The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
You can also download the attestation from GitHub and verify against that directly:
0.15.18: 0.15.18Compare source
Source
Release Notes
Released on 2026-06-18.
Preview features
ruff:ignorecomments (#25791)pydocstyle] Prevent property docstrings starting with verbs (D421) (#23775)flake8-pyi] ExtendPYI033to Python files (#26129)Bug fixes
Rule changes
flake8-pyi] RenamePYI033tolegacy-type-comment(#26131)Performance
ThinVecfor call keywords (#25999)Server
Documentation
flake8-tidy-imports] Add fix safety section (TID252) (#17491)Parser
__debug__lambda parameters (#26022)_as a match-pattern target (#25977)yieldexpressions after commas (#26024)Playground
Contributors
Install ruff 0.15.18
Install prebuilt binaries via shell script
Install prebuilt binaries via powershell script
Download ruff 0.15.18
Verifying GitHub Artifact Attestations
The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
You can also download the attestation from GitHub and verify against that directly:
0.15.19: 0.15.19Compare source
Source
Release Notes
Released on 2026-06-23.
Preview features
Bug fixes
Rule changes
pylint] Update fix suggestions for__floor__,__trunc__,__length_hint__, and__matmul__variants (PLC2801) (#26239)Performance
Documentation
flake8-pyi] Note thatPYI051is an opinionated stylistic rule (#26179)pyupgrade] ClarifyUP029as a Python 2 compatibility rule (#26243)Other changes
Contributors
Install ruff 0.15.19
Install prebuilt binaries via shell script
Install prebuilt binaries via powershell script
Download ruff 0.15.19
Verifying GitHub Artifact Attestations
The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
You can also download the attestation from GitHub and verify against that directly:
0.15.20: 0.15.20Compare source
Source
Release Notes
Released on 2026-06-25.
Preview features
noqashebang handling inruff:ignorecomments (#26286)ruff] Removepytest-fixture-autouse(RUF076) (#26240, #26371)Documentation
ruff_python_parserREADME for crates.io (#26315)perflint] Clarify thatPERF402applies to any iterable (#26242)Contributors
Install ruff 0.15.20
Install prebuilt binaries via shell script
Install prebuilt binaries via powershell script
Download ruff 0.15.20
Verifying GitHub Artifact Attestations
The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
You can also download the attestation from GitHub and verify against that directly:
0.15.21: 0.15.21Compare source
Source
Release Notes
Released on 2026-07-09.
Preview features
--add-ignorefor addingruff:ignorecomments (#26346)flake8-comprehensions] DropC409tuple comprehension preview behavior (#25707)pyupgrade] Lint and fix use of deprecatedabcdecorators (UP051) (#26417)Bug fixes
flake8-implicit-str-concat] FixISC003autofix incorrectly stripping+from comments (#26554)Rule changes
flake8-executable] MarkEXE004fix as unsafe (#26033)flake8-pyi] MarkPYI061fixes as unsafe in Python files (#26533)pydocstyle] Skipoverload-with-docstringin stub files (D418) (#26318)Performance
fits_elementin formatter (#26429)Formatter
--extend-excludetoruff format(#26372)Documentation
flake8-bandit] Fix misleading docstring formako-templates(S702) (#26432)ruff] Fix non-triggering example forif-key-in-dict-del(RUF051) (#26433)Contributors
Install ruff 0.15.21
Install prebuilt binaries via shell script
Install prebuilt binaries via powershell script
Download ruff 0.15.21
Verifying GitHub Artifact Attestations
The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
You can also download the attestation from GitHub and verify against that directly:
0.15.22: 0.15.22Compare source
Source
Release Notes
Released on 2026-07-16.
Preview features
pycodestyle] Add an autofix forE402(#22212)refurb] Allow subclassing builtins in stub files (FURB189) (#26812)ruff] Add rule to replacenoqacomments withruff:ignore(RUF105) (#26423)ruff] Add rule to use human-readable names inruff:ignorecomments (RUF106) (#26682)ruff] Add rule to use human-readable names in configuration selectors (RUF201) (#26772)Bug fixes
flake8-pyi] Fix false positive in__all__(PYI053) (#26872)Rule changes
pylint] Ignore mutable type updates inredefined-loop-name(PLW2901) (#25733)Performance
Documentation
flake8-datetimez] Clarify naming guidance fordatetime.today(DTZ002) (#26658)pycodestyle] DocumentE731fix safety (#26847)ruff] Clarify intentional async contexts forunused-async(RUF029) (#26641)Contributors
Install ruff 0.15.22
Install prebuilt binaries via shell script
Install prebuilt binaries via powershell script
Download ruff 0.15.22
Verifying GitHub Artifact Attestations
The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
You can also download the attestation from GitHub and verify against that directly:
0.16.0: 0.16.0Breaking change detected.
Compare source
Source
Release Notes
Released on 2026-07-23.
Check out the blog post for a migration guide and overview of the changes!
Breaking changes
Ruff now enables a much larger set of rules by default (413, up from 59). See the blog post for more details and the new Default Rules page for a full listing of the enabled rules. Note that this is primarily an expansion, but 18 of the more opinionated pycodestyle (
E) and pyflakes (F) rules have been removed from the default set:E401,E402,E701,E702,E703,E711,E712,E713,E714,E721,E731,E741,E742,E743,F403,F405,F406, andF722.Ruff can now format Python code blocks in Markdown files and will do this by default. See the documentation for more details.
Ruff now supports
ruff: ignorecomments at the ends of lines, likenoqacomments, or on the line preceding a diagnostic. For example, these both suppress anunused-import(F401) diagnostic:Fixes are now shown in
checkandformat --checkoutput:This example also shows off the Markdown formatting.
format --checknow supports the same output formats as the linter, including thegithubandgitlaboutputs for rendering annotations in CI:See the CLI help or documentation for the full list of supported formats.
The
filename,location,end_location,fix.edits[].location, andfix.edits[].end_locationfields in the JSON output format may now benullrather than defaulting to the empty string and row 1, column 1, respectively.Stabilization
The following rules have been stabilized and are no longer in preview:
airflow3-incompatible-function-signature(AIR303)missing-copyright-notice(CPY001)unnecessary-from-float(FURB164)sorted-min-max(FURB192)implicit-string-concatenation-in-collection-literal(ISC004)log-exception-outside-except-handler(LOG004)invalid-bool-return-type(PLE0304)too-many-positional-arguments(PLR0917)stop-iteration-return(PLR1708)none-not-at-end-of-union(RUF036)access-annotations-from-class-dict(RUF063)duplicate-entry-in-dunder-all(RUF068)The following behaviors have been stabilized:
blind-except(BLE001) is now suppressed when the exception is logged vialoggingmethods other thancritical,errorandexception.future-required-type-annotation(FA102) now checks for additional PEP 585-compatible APIs, such as those fromcollections.abc.f-string-in-get-text-func-call(INT001),format-in-get-text-func-call(INT002), andprintf-in-get-text-func-call(INT003) now check for additional common ways of using thegettextmodule, such as assigning it tobuiltins._.suspicious-url-open-usage(S310) now resolves local string literal bindings to avoid more false positives.snmp-insecure-version(S508) andsnmp-weak-cryptography(S509) now support the recommended API from newer versions of PySNMP.typing-text-str-alias(UP019) now recognizestyping_extensions.Textin addition totyping.Text.Preview features
pyupgrade] Fix false positive withTypeVardefault before Python 3.13 (UP040) (#26888)Bug fixes
ruff] Fix missing check on unrecognized early bound (RUF016) (#26986)Rule changes
Performance
pyupgrade] Speed upunnecessary-future-import(UP010) (#27047)Documentation
ruff] Add missing period in "Why is this bad?" section (RUF200) (#26930)flake8-simplify] Clarifyos.environbehavior on Windows (SIM112) (#26972)pydocstyle] Document fix safety (D400) (#26971)Contributors
Install ruff 0.16.0
Install prebuilt binaries via shell script
Install prebuilt binaries via powershell script
Download ruff 0.16.0
Verifying GitHub Artifact Attestations
The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
You can also download the attestation from GitHub and verify against that directly:
0.16.1: 0.16.1Compare source
Source
Release Notes
Released on 2026-07-30.
Preview features
flake8-pytest-style] Make fixes safe by default and unsafe only when comments are present (PT018) (#27201)pyupgrade] Skip fix when a defaultedTypeVarprecedes a non-defaulted one (UP040,UP046,UP047) (#27133)ruff] Fix false positive with unpacked arguments (RUF065) (#26959)Bug fixes
gen-lsp-typesto gracefully handle unknown enumeration values in LSP messages (#27230)flake8-bugbear] Markrangeas immutable (B008) (#27247)flake8-comprehensions] NFKC-normalize keyword names inC408fix (#26813)flake8-return] Fix false positive when variable is read infinallyclause (RET504) (#25441)pydocstyle] Skip section detection inside RST directive bodies (D214,D405,D413) (#23635)refurb] Parenthesizeyieldarguments in theFURB192fix (#27192)Rule changes
flake8-pytest-style] MarkPT022fixes as unsafe (#26440)refurb] Mark fixes that remove unknown separators as unsafe (FURB105) (#27200)Server
Documentation
pyconMarkdown formatting (#27153)flake8-bandit] DocumentTYPE_CHECKINGexception (S101) (#27004)flake8-import-conventions] Document thatextend-aliasescan override default aliases (#27191)pylint] Add missing fix safety gotchas fornon-augmented-assignment(PLR6104) (#27250)Other changes
Contributors
Install ruff 0.16.1
Install prebuilt binaries via shell script
Install prebuilt binaries via powershell script
Download ruff 0.16.1
Verifying GitHub Artifact Attestations
The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
You can also download the attestation from GitHub and verify against that directly:
0.16.2: 0.16.2Compare source
Source
Release Notes
Released on 2026-08-06.
Bug fixes
flake8-pyi] Avoid false positives onsingledispatchfunctions (PYI041) (#27335)Server
Contributors
Install ruff 0.16.2
Install prebuilt binaries via shell script
Install prebuilt binaries via powershell script
Download ruff 0.16.2
Verifying GitHub Artifact Attestations
The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
You can also download the attestation from GitHub and verify against that directly:
0.16.3: 0.16.3Compare source
Source
Release Notes
Released on 2026-08-13.
Preview features
pylint] Fix false negatives on negative numbers (PLR6104) (#27251)pyupgrade] Add rule to replacewhile 1withwhile True(UP048) (#27190)Bug fixes
flake8-bandit] Also check keyword arguments (S602,S603,S607,S609) (#27687)pylint] Allowcontinueinfinallyon Python 3.8 (#27626)pylint] FixPLE1307false positive with bools (#27651)pylint] Fix false positives and negatives with%bformat character (PLE1300,PLE1307) (#27560)pylint] Improve handling of concatenated strings (PLE1300) (#27659)Rule changes
numpy] Makenp.chararrayautofix backwards-compatible (NPY201) (#27527)Performance
Exprsize to 64 bytes (#27591)CLI
ruff check --statisticsoutput (#27646)Documentation
ruff] Also suggestasyncio.TaskGroup(RUF006) (#27461)Other changes
Contributors
Install ruff 0.16.3
Install prebuilt binaries via shell script
Install prebuilt binaries via powershell script
Download ruff 0.16.3
Verifying GitHub Artifact Attestations
The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
You can also download the attestation from GitHub and verify against that directly:
0.16.4: 0.16.4Compare source
Source
Release Notes
Released on 2026-08-20.
Preview features
flake8-use-pathlib] Add autofix forPTH116(#26460)refurb] Restrictdelete-full-sliceto lists (FURB131) (#27711)refurb] SkipFURB101andFURB103when theopenargument is a file descriptor (#27643)Bug fixes
InvalidInstructionon Windows CPUs that do not supportPOPCNT(#27803)pyflakes] Emit semantic syntax errors in string type definitions asF722(#27835)pylint] Allowos._exitimports inimport-private-name(PLC2701) (#27738)Rule changes
ruff] Addctypes.LittleEndianStructureand related types to existing exception (RUF012) (#27753)nonlocal(#27628)Server
Documentation
Other changes
Contributors
Install ruff 0.16.4
Install prebuilt binaries via shell script
Install prebuilt binaries via powershell script
Download ruff 0.16.4
Verifying GitHub Artifact Attestations
The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
You can also download the attestation from GitHub and verify against that directly:
0.16.5: 0.16.5Compare source
Source
Release Notes
Released on 2026-08-27.
Preview features
Bug fixes
flake8-async] Detect blocking generic HTTP requests (ASYNC210) (#28024)flake8-datetimez] Allow timezone-safestrptimechains (DTZ007) (#28023)flake8-simplify] Respect side effects inlambdadefaults (SIM401) (#28000)Server
ClientOptionsdoc comment (#27978)Documentation
Contributors
Install ruff 0.16.5
Install prebuilt binaries via shell script
Install prebuilt binaries via powershell script
Download ruff 0.16.5
Verifying GitHub Artifact Attestations
The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
You can also download the attestation from GitHub and verify against that directly:
0.16.6: 0.16.6Compare source
Source
Release Notes
Released on 2026-09-03.
Preview features
pytest-fixture-autouseto therestrictioncategory (#28219)flake8-pytest-style] Add an autofix forPT020(#27993)flake8-tidy-imports] Prevent fix loop betweenTID254andTID255(#28262)isort] Exclude pragma comments from line length calculation (I001) (#27313)Bug fixes
flake8-async,pylint] Recognizebuiltins.open(ASYNC230,PLW1514) (#28021)flake8-bugbear] Fix panic onmatchsubjects (B031) (#27781)flake8-datetimez] Rejecttzinfo=Nonefordatetimebounds (DTZ901) (#28022)flake8-pytest-style] Avoid duplicatePT017diagnostics (#27918)ruff] Removelint.externalhint for Ruff-specific suppressions (RUF102) (#27923)Rule changes
flake8-use-pathlib] Add display-only fix foros.listdir(PTH208) (#28027)Documentation
lint.per-file-ignores(#28106)flake8-async] Document thread offloading (ASYNC240) (#28008)pyupgrade] Clarify defaultencodingargument handling (UP012) (#27315)Other changes
Contributors
Install ruff 0.16.6
Install prebuilt binaries via shell script
Install prebuilt binaries via powershell script
Download ruff 0.16.6
Verifying GitHub Artifact Attestations
The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
You can also download the attestation from GitHub and verify against that directly:
0.16.7: 0.16.7Compare source
Source
Release Notes
Released on 2026-09-10.
Preview features
ruff] Add rule for default values on method receivers (RUF077) (#26700)ruff] Recognizere.prefixmatch(RUF039,RUF055) (#28311)Bug fixes
flake8-implicit-str-concat] Mark fix unsafe when it creates a docstring (ISC003) (#27981)flake8-tidy-imports] Skip fixes for multi-member imports (TID254) (#26584)pylint] GateImportCycleErroron Python 3.15 (PLW0133) (#28310)Rule changes
D211andD203rule conflict diagnostic (#28444)sliceandfrozendictgenerics (#28477)__cached__for Python 3.15 (#28476)pyupgrade] Stop recommending removedtyping.no_type_check_decorator(UP035) (#28475)Performance
Documentation
line-lengthpath in--configexample (#28392)Other changes
Contributors
Install ruff 0.16.7
Install prebuilt binaries via shell script
Install prebuilt binaries via powershell script
Download ruff 0.16.7
Verifying GitHub Artifact Attestations
The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
You can also download the attestation from GitHub and verify against that directly:
0.16.8: 0.16.8Compare source
Source
Release Notes
Released on 2026-09-16.
Bug fixes
TypedDictkeyword arguments correctly (#28584)flake8-simplify] Detect nestedasync withunder sync parent (SIM117) (#27821)flake8-simplify] Preserve operand order inSIM109fix (#27824)pyupgrade] Preserve required parentheses in multilineUP040fixes (#28164)pyupgrade] SkipTypeVarTupleandParamSpecconversions with bounds or constraints (UP040,UP046,UP047) (#28505)Rule changes
__lazy_modules__(#28459)TypedDictclass keywords (#28533)typing.TypeForm(#28507)__lazy_modules__(#28491)flake8-type-checking] Prefer lazy imports overTYPE_CHECKINGon Python 3.15 and later (TC001,TC002,TC003) (#28541)pyupgrade] Make the fix forUP040always unsafe (#28526)pyupgrade] Stop recommending deprecatedByteStringaliases (UP035) (#28498)ruff,flake8-use-pathlib] Recognize theparent_modeargument (RUF064,PTH103) (#28528)ruff] Detect\Zinpytest.raises()match patterns (RUF043) (#28598)CLI
Configuration
flake8-tidy-imports] Addextend-banned-api(#28644)Contributors
Install ruff 0.16.8
Install prebuilt binaries via shell script
Install prebuilt binaries via powershell script
Download ruff 0.16.8
Verifying GitHub Artifact Attestations
The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
You can also download the attestation from GitHub and verify against that directly:
0.16.9: 0.16.9Compare source
Source
Release Notes
Released on 2026-09-24.
Preview features
ruff] Avoid false positives for overloaded division (RUF069) (#28309)Bug fixes
flake8-bugbear] Avoid false positives for calls with keyword arguments (B009,B010,B043) (#28776)flake8-tidy-imports] Allow lazy imports to be used in deferred annotations (TID255) (#28767)Rule changes
flake8-pyi] Mention stubs in the diagnostic message (PYI002) (#28542)Documentation
flake8-annotations] Clarify thatANN401checks return types in addition to arguments (#28334)flake8-bugbear] Document type-checker interaction (B010) (#28509)flake8-comprehensions] Documentmap/generator exception behavior (C417) (#27794)ruff] Mention related isort settings (RUF022) (#28719)Contributors
Install ruff 0.16.9
Install prebuilt binaries via shell script
Install prebuilt binaries via powershell script
Download ruff 0.16.9
Verifying GitHub Artifact Attestations
The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
You can also download the attestation from GitHub and verify against that directly:
typing-extensions (current version → 4.16.0)
Source comparison unavailable: source refs for this transition are not known.
3.6.23.6.2.13.6.53.6.63.7.23.7.43.7.4.13.7.4.23.7.4.33.10.0.03.10.0.13.10.0.24.0.04.0.14.1.04.1.14.2.04.3.04.4.04.5.04.6.04.6.14.6.24.6.34.7.0: 4.7.0Source
Source ref:
mainThis is a feature release. Major changes include:
typingare now re-exported bytyping_extensionsfor conveniencetyping_extensions.get_protocol_membersandtyping_extensions.is_protocolFull changelog of versions 4.7.0 and 4.7.0rc1:
Release 4.7.0 (June 28, 2023)
which reaches its end of life on June 27, 2023. Version 4.8.0 will support
only Python 3.8.0 and up.
typing_extensions.Protocolclass that had one or morenon-callable members would raise
TypeErrorwhenissubclass()was called against it, even if it defined a custom
__subclasshook__method. The correct behaviour -- which has now been restored -- is not to
raise
TypeErrorin these situations if a custom__subclasshook__methodis defined. Patch by Alex Waygood (backporting
https://github.com/python/cpython/pull/105976).
Release 4.7.0rc1 (June 21, 2023)
typing_extensions.get_protocol_membersandtyping_extensions.is_protocol(backport of CPython PR #104878).Patch by Jelle Zijlstra.
typing_extensionsnow re-exports all names in the standard library'stypingmodule, except the deprecatedByteString. Patch by JelleZijlstra.
typing_extensions.Protocol,typing.runtime_checkablecan now be used ontyping_extensions.Protocol(previously, users had to use
typing_extensions.runtime_checkableif theywere using
typing_extensions.Protocol).TypedDictwith the implementation in thestandard library on Python 3.9 and higher.
typing_extensions.TypedDictis now a function instead of a class. Theprivate functions
_check_fails,_dict_new, and_typeddict_newhave been removed.
is_typeddictnow returnsFalsewhen called withTypedDictitself as the argument. Patch by Jelle Zijlstra.TypedDictclasses through the keyword-argument syntax. Patch byJelle Zijlstra.
issubclass(object, typing_extensions.Protocol)would erroneously raiseTypeError. Patch by Alex Waygood (backporting the CPython PRhttps://github.com/python/cpython/pull/105239).
Protocolclasses to inherit fromtyping_extensions.Bufferorcollections.abc.Buffer. Patch by Alex Waygood (backportinghttps://github.com/python/cpython/pull/104827, by Jelle Zijlstra).
typing.Protocolandtyping_extensions.Protocolsimultaneously. Since v4.6.0, this caused
TypeErrorto be raised due to ametaclass conflict. Patch by Alex Waygood.
create
TypedDicts andNamedTuples. CPython PRs #105609 and #105780by Alex Waygood;
typing_extensionsbackport by Jelle Zijlstra.NamedTupleusing the functional syntax with keyword arguments(
NT = NamedTuple("NT", a=int)) is now deprecated.NamedTuplewith zero fields using the syntaxNT = NamedTuple("NT")or
NT = NamedTuple("NT", None)is now deprecated.TypedDictwith zero fields using the syntaxTD = TypedDict("TD")or
TD = TypedDict("TD", None)is now deprecated.Xthat had a memberawould not beconsidered an implicit subclass of an unrelated protocol
Ythat only has amember
a. Where the members ofXare a superset of the members ofY,Xshould always be considered a subclass ofYiffYis aruntime-checkable protocol that only has callable members. Patch by Alex
Waygood (backporting CPython PR
https://github.com/python/cpython/pull/105835).
4.7.1: 4.7.1Source
Source ref:
mainTypedDict,NamedTupleandis_protocolon PyPy-3.7 andPyPy-3.8. Patch by Alex Waygood. Note that PyPy-3.7 and PyPy-3.8 are unsupported
by the PyPy project. The next feature release of typing-extensions will
drop support for PyPy-3.7 and may also drop support for PyPy-3.8.
4.8.0: 4.8.0Source
Source ref:
mainChanges since 4.7.1:
typing_extensions.Doc, as proposed by PEP 727. Patch bySebastián Ramírez.
get_original_bases()would return incorrect results whencalled on a concrete subclass of a generic class. Patch by Alex Waygood
(backporting https://github.com/python/cpython/pull/107584, by James
Hilton-Balfe).
ParamSpec(default=...)would raise aTypeErroron Pythonversions <3.11. Patch by James Hilton-Balfe
No changes since 4.8.0rc1.
4.9.0: 4.9.0Source
Source ref:
mainThis feature release adds
typing_extensions.ReadOnly, as specifiedby PEP 705, and makes various other improvements, especially to
@typing_extensions.deprecated().There are no changes since 4.9.0rc1.
4.10.0Source
Source ref:
mainRelease 4.10.0 (February 25, 2024)
This feature release adds support for PEP 728 (TypedDict with extra
items) and PEP 742 (
TypeIs).There are no changes since 4.10.0rc1.
4.11.0: 4.11.0Source
Source ref:
mainRelease 4.11.0 (April 5, 2024)
This feature release provides improvements to various recently
added features, most importantly type parameter defaults (PEP 696).
There are no changes since 4.11.0rc1.
Changes since 4.10.0:
Patch by Nadir Chowdhury.
typingand
typing_extensionson Python 3.10. Patch by Jelle Zijlstra.include_extra=False,get_type_hints()now stripsReadOnlyfrom the annotation.4.12.0: 4.12.0Source
Source ref:
mainThis release focuses on compatibility with the upcoming release of
Python 3.13. Most changes are related to the implementation of type
parameter defaults (PEP 696).
Thanks to all of the people who contributed patches, especially Alex
Waygood, who did most of the work adapting typing-extensions to the
CPython PEP 696 implementation.
There is a single change since 4.12.0rc1:
typing_extensions.ParamSpecon Python 3.8 and3.9 that meant that
isinstance(typing_extensions.ParamSpec("P"), typing.TypeVar)would have adifferent result in some situations depending on whether or not a profiling
function had been set using
sys.setprofile. Patch by Alex Waygood.Changes included in 4.12.0rc1:
typing.NoDefaultsentinel object from Python 3.13.TypeVars, ParamSpecs and TypeVarTuples without default values now have
their
__default__attribute set to this sentinel value.has_default()method, matching
typing.TypeVar,typing.ParamSpecandtyping.TypeVarTupleon Python 3.13+.default=Nonepassed totheir constructors now have their
__default__attribute set toNoneat runtime rather than
types.NoneType.TypeVar,ParamSpecandTypeVarTupleon Python3.13.0b1 and newer.
allowing type parameters without default values to follow those with
default values in some type parameter lists. Patch by Alex Waygood,
backporting a CPython PR by Jelle Zijlstra.
TypeVarwith a default value after aTypeVarTuplein a type parameter list. This matches the CPythonimplementation of PEP 696 on Python 3.13+.
ParamSpecwould be cast to a tuple if a list was provided.
Patch by Alex Waygood.
Protocoltests on Python 3.13.0a6 and newer. 3.13.0a6 adds a new__static_attributes__attribute to all classes in Python,which broke some assumptions made by the implementation of
typing_extensions.Protocol. Similarly, 3.13.0b1 adds the new__firstlineno__attribute to all classes.AttributeErrorwhen usingtyping_extensions.runtime_checkablein combination with
typing.Protocolon Python 3.12.2 or newer.Patch by Alex Waygood.
assert_nevernow includes the repr of the argumentin the
AssertionError. Patch by Hashem, backporting of the originalfix https://github.com/python/cpython/pull/91720 by Jelle Zijlstra.
typing_extensions.Generator,and the second parameter of
typing_extensions.AsyncGenerator,now default to
None. This matches the behaviour oftyping.Generatorand
typing.AsyncGeneratoron Python 3.13+.typing_extensions.ContextManagerandtyping_extensions.AsyncContextManagernow have an optional secondparameter, which defaults to
Optional[bool]. The new parametersignifies the return type of the
__(a)exit__method, matchingtyping.ContextManagerandtyping.AsyncContextManageron Python3.13+.
types.CapsuleTypefrom Python 3.13.improving the security of the release process. Patch by Jelle Zijlstra.
4.12.1: 4.12.1Source
Source ref:
mainof PEP 649 in Python 3.14. Patch by Jelle Zijlstra.
Annotatedtypes would causeTypeErrorto be raised if the nestedAnnotatedtype had unhashablemetadata. Patch by Alex Waygood.
4.12.2: 4.12.2Source
Source ref:
main__eq__method would raise errors. Patch by Jelle Zijlstra.4.13.0Source
Source ref:
mainNew features:
typing_extensions.TypeFormfrom PEP 747. Patch byJelle Zijlstra.
typing_extensions.get_annotations, a backport ofinspect.get_annotationsthat adds features specifiedby PEP 649. Patches by Jelle Zijlstra and Alex Waygood.
evaluate_forward_reffrom CPython PR#119891 to evaluate
ForwardRefs.Patch by Daraan, backporting a CPython PR by Jelle Zijlstra.
Bugfixes and changed features:
with
@typing_extensions.deprecated. Patch by Sebastian Rittau.TypeAliasTypeinstances could be subscripted evenwhere they were not generic. Patch by Daraan.
TypeAliasTypeinstance did not have allattributes of the original
TypeAliasTypeinstance on older Python versions.Patch by Daraan and Alex Waygood.
TypeAliasTypeinstances (and some othersubscripted objects) had wrong parameters if they were directly
subscripted with an
Unpackobject.Patch by Daraan.
...in genericCallablealiases that have a
Concatenatespecial form as their argument.Patch by Daraan.
Concatenatebackport for Python 3.8-3.10 to now acceptEllipsisas an argument. Patch by Daraan.get_type_hintsto reflect Python 3.11+ behavior which does not addUnion[..., NoneType]to annotations that have aNonedefault value anymore.This fixes wrapping of
Annotatedin an unwantedOptionalin such cases.Patch by Daraan.
Unpackaliases causing nested Unpacksto not be resolved correctly. Patch by Daraan.
fix
TypeAliasTypenot raising an error on non-tuple inputs fortype_params.Patch by Daraan.
...could not be used for parameter expressions forTypeAliasTypeinstances before Python 3.11.
Patch by Daraan.
typing.Concatenateandtyping_extensions.Concatenatetogether. Patch by Daraan.to reflect Python 3.13+ behavior: A value assigned to
__total__in the class body of aTypedDictwill be overwritten by thetotalargument of theTypedDictconstructor.Patch by Daraan, backporting a CPython PR by Jelle Zijlstra.
isinstance(typing_extensions.Unpack[...], TypeVar)now evaluates toFalseon Python 3.11and newer, but remains
Trueon versions before 3.11.Patch by Daraan.
4.13.1Source
Source ref:
mainThis is a bugfix release fixing two edge cases that appear on old bugfix releases of CPython.
Bugfixes:
TypeErrorwhen usingConcatenate.Patch by Daraan.
TypeErrorwhen usingevaluate_forward_refon Python 3.10.1-2 and 3.9.8-10.Patch by Daraan.
4.13.2Source
Source ref:
mainTypeErrorwhen taking the union oftyping_extensions.TypeAliasTypeand atyping.TypeAliasTypeon Python 3.12 and 3.13.Patch by Joren Hammudoglu.
to avoid having user arguments shadowed in generated
__new__by@typing_extensions.deprecated.Patch by Victorien Plot.
4.14.0Source
Source ref:
mainThis release adds several new features, including experimental support for inline typed dictionaries (PEP 764) and sentinels (PEP 661), and support for changes in Python 3.14. In addition, Python 3.8 is no longer supported.
Changes since 4.14.0rc1:
__or__and__ror__methods fromtyping_extensions.Sentinelon Python versions <3.10. PEP 604 was introduced in Python 3.10, and
typing_extensionsdoes not generally attempt to backport PEP-604 methodsto prior versions.
typing_extensions.evaluate_forward_refwith changes in Python 3.14.Changes included in 4.14.0rc1:
typing,anticipating the removal of
typing.no_type_check_decoratorin Python 3.15.Patch by Jelle Zijlstra.
typing_extensions.Format,typing_extensions.evaluate_forward_ref, andtyping_extensions.TypedDictto alignwith changes in Python 3.14. Patches by Jelle Zijlstra.
New features:
Patch by Victorien Plot.
typing_extensions.Readerandtyping_extensions.Writer. Patch bySebastian Rittau.
Victorien Plot.
4.14.1Source
Source ref:
mainRelease 4.14.1 (July 4, 2025)
typing_extensions.TypedDictnested inside other types(e.g.,
typing.Type[typing_extensions.TypedDict]). This is not allowed by thetype system but worked on older versions, so we maintain support.
4.15.0: 4.15.0Source
Source ref:
mainNo user-facing changes since 4.15.0rc1.
New features since 4.14.1:
@typing_extensions.disjoint_basedecorator, as specifiedin PEP 800. Patch by Jelle Zijlstra.
typing_extensions.type_repr, a backport ofannotationlib.type_repr,introduced in Python 3.14 (CPython PR #124551,
originally by Jelle Zijlstra). Patch by Semyon Moroz.
typing_extensions.evaluate_forward_ref. Backport ofCPython PR #137227 by Jelle Zijlstra.
4.16.0: 4.16.0Source
Source ref:
mainNo changes since 4.16.0rc2.
Changes since 4.15.0:
typing_extensions.TypeAliasType's__module__attribute writable. Backport of CPython PR #149172.__required_keys__and__optional_keys__when inheriting keys with the same name.AsyncIterator,io.Reader,io.Writerandos.PathLikeprotocols as bases for other protocols.isinstancewithtyping_extensions.Concatenate[...]ortyping_extensions.Unpack[...]as the first argument could have a different result in some situations depending on whether or not a profiling function had been set usingsys.setprofile. This affected both CPython and PyPy implementations. Patch by Brian Schubert.__init_subclass__()behavior in the presence of multiple inheritance involving an@deprecated-decorated base class. Backport of CPython PR #138210 by Brian Schubert.TypeErrorwhen attempting to subclasstyping_extensions.ParamSpecon Python 3.9. Thetypingimplementation has always raised an error, and thetyping_extensionsimplementation has raised an error on Python 3.10+ sincetyping_extensionsv4.6.0. Patch by Brian Schubert.bound,covariant,contravariant, andinfer_varianceparameters toTypeVarTuple.bound,covariant,contravariantandinfer_varianceparameters toParamSpec. Improve the validation of these parameters at runtime.typing_extensions.Sentineltotyping_extensions.sentinel, following the name that has been adopted forbuiltins.sentinelon Python 3.15.typing_extensions.Sentinelis retained as a soft-deprecated alias for backwards compatibility.nameas a keyword argument orrepras a positional argument to thesentinelconstructor.X = sentinel("X")is nowXrather than<X>.DeprecationWarningwhendeprecatedis applied to a coroutine function on Python 3.14.0.watchfiles (1.2.0 → 1.3.0)
1.3.0: v1.3.0 2026-09-21Compare source
Source
Source ref:
mainWhat's Changed
New Contributors
Full Changelog: https://github.com/samuelcolvin/watchfiles/compare/v1.2.0...v1.3.0
yarl (1.22.0 → 1.25.1)
Source comparison unavailable: source refs for this transition are not known.
1.23.01.24.21.24.51.25.157480ee4766e1306e940