Changelog¶
6.7.1¶
(2026-01-25)
Bug fixes¶
6.7.0¶
(2025-10-05)
Contributor-facing changes¶
Updated tests and added CI for CPython 3.14 – by @kumaraditya303.
Related issues and pull requests on GitHub: #1235.
6.6.4¶
(2025-08-11)
Bug fixes¶
Contributor-facing changes¶
The type preciseness coverage report generated by MyPy is now uploaded to Coveralls and will not be included in the Codecov views going forward – by @webknjaz.
Added memory leak test for popping or deleting attributes from a multidict to prevent future issues or bogus claims. – by @Vizonex
Related issues and pull requests on GitHub: #1233.
6.6.3¶
(2025-06-30)
Bug fixes¶
Fixed inconsistencies generated by the C implementation of
_md_shrink()which might later lead to assertion failures and crash – by @Romain-Geissler-1A.Related issues and pull requests on GitHub: #1229.
6.6.2¶
(2025-06-28)
Bug fixes¶
Fixed a memory corruption issue in the C implementation of
_md_shrink()that could lead to segmentation faults and data loss when items were deleted from aMultiDict. The issue was an edge case in the pointer arithmetic during the compaction phase – by @bdraco.Fixed format string compilation errors in debug builds on 32-bit platforms by using portable
%zdformat specifiers forPy_ssize_tvalues instead of%ld– by @bdraco.
Packaging updates and notes for downstreams¶
6.6.1¶
(2025-06-28)
Bug fixes¶
If
multidict.MultiDict.extend(),multidict.MultiDict.merge(), ormultidict.MultiDict.update()raises an exception, now the multidict internal state is correctly restored. Patch by @asvetlov.Related issues and pull requests on GitHub: #1215.
Contributor-facing changes¶
6.6.0¶
(2025-06-27)
Features¶
Added
multidict.MultiDict.merge()which copies all items from arguments if its key not exist in the dictionary – by @asvetlov.Related issues and pull requests on GitHub: #292.
Stopped reallocating memory for the internal
htkeys_tstructure when inserting new items if the multidict has deleted items and it could be collapsed in-place. Removal ofmalloc()/free()improves the performance slightly.The change affects C implementation only, pure Python code is not changed.
Patch by @asvetlov.
Related issues and pull requests on GitHub: #1200.
C implementation of
multidict.MultiDict.getallnow is slightly faster if it returns nothing – by @asvetlov.Related issues and pull requests on GitHub: #1212.
Improved documentation¶
Replaced docstring for
multidict.MultiDict.update()to don’t use RST/markdown markup.Related issues and pull requests on GitHub: #1203.
Improved documentation for
multidict.MultiDict.extend()andmultidict.MultiDict.update()– by @asvetlov.Related issues and pull requests on GitHub: #1205.
Contributor-facing changes¶
When building wheels, the source distribution is now passed directly to the
cibuildwheelinvocation – by @webknjaz.Related issues and pull requests on GitHub: #1199.
Set up
PYTHONHASHSEEDfor benchmarks execution to make measured times stable – by @asvetlov.Related issues and pull requests on GitHub: #1202.
6.5.1¶
(2025-06-24)
Bug fixes¶
Contributor-facing changes¶
A pair of code formatters for Python and C have been configured in the pre-commit tool.
Related issues and pull requests on GitHub: #1123.
Shorted fixture parametrization ids.
For example,
test_keys_view_xor[case-insensitive-pure-python-module]becomestest_keys_view_xor[ci-py]– by @asvetlov.Related issues and pull requests on GitHub: #1192.
The
reusable-cibuildwheel.ymlworkflow has been refactored to be more generic andci-cd.ymlnow holds all the configuration toggles – by @webknjaz.Related issues and pull requests on GitHub: #1193.
6.5.0¶
(2025-06-17)
Note
The release was yanked because of #1195, multidict 6.5.1 should be used instead.
Features¶
Replace internal implementation from an array of items to hash table. algorithmic complexity for lookups is switched from O(N) to O(1).
The hash table is very similar to
dictfrom CPython but it allows keys duplication.The benchmark shows 25-50% boost for single lookups, x2-x3 for bulk updates, and x20 for some multidict view operations. The gain is not for free:
addandextendare 25-50% slower now. We consider it as acceptable because the lookup is much more common operation that addition for the library domain.Related issues and pull requests on GitHub: #1128.
Contributor-facing changes¶
Builds have been added for arm64 Windows wheels and the
reusable-build-wheel.ymltemplate has been modified to allow for an os value (windows-11-arm) which does not end with the-latestpostfix.Related issues and pull requests on GitHub: #1167.
6.4.4¶
(2025-05-19)
Bug fixes¶
Fixed a segmentation fault when calling
multidict.MultiDict.setdefault()with a single argument – by @bdraco.Related issues and pull requests on GitHub: #1160.
Fixed a segmentation fault when attempting to directly instantiate view objects (
multidict._ItemsView,multidict._KeysView,multidict._ValuesView) – by @bdraco.View objects now raise a proper
TypeErrorwith the message “cannot create ‘…’ instances directly” when direct instantiation is attempted.View objects should only be created through the proper methods:
multidict.MultiDict.items(),multidict.MultiDict.keys(), andmultidict.MultiDict.values().Related issues and pull requests on GitHub: #1164.
Miscellaneous internal changes¶
multidict.MultiDictProxywas refactored to rely only onmultidict.MultiDictpublic interface and don’t touch any implementation details.Related issues and pull requests on GitHub: #1150.
Multidict views were refactored to rely only on
multidict.MultiDictAPI and don’t touch any implementation details.Related issues and pull requests on GitHub: #1152.
Dropped internal
_Implclass from pure Python implementation, both pure Python and C Extension follows the same design internally now.Related issues and pull requests on GitHub: #1153.
6.4.3¶
(2025-04-10)
Bug fixes¶
Packaging updates and notes for downstreams¶
Added the ability to build in debug mode by setting
MULTIDICT_DEBUG_BUILDin the environment – by @bdraco.Related issues and pull requests on GitHub: #1145.
6.4.2¶
(2025-04-09)
Bug fixes¶
6.4.1¶
(2025-04-09)
No significant changes.
6.4.0¶
(2025-04-09)
Bug fixes¶
Fixed a memory leak creating new
istrobjects – by @bdraco.The leak was introduced in 6.3.0
Related issues and pull requests on GitHub: #1133.
Fixed reference counting when calling
multidict.MultiDict.update()– by @bdraco.The leak was introduced in 4.4.0
Related issues and pull requests on GitHub: #1135.
Features¶
6.3.2¶
(2025-04-03)
Bug fixes¶
6.3.1¶
(2025-04-01)
Bug fixes¶
Fixed keys not becoming case-insensitive when
multidict.CIMultiDictis created by passing in amultidict.MultiDict– by @bdraco.Related issues and pull requests on GitHub: #1112.
Fixed the pure Python version mutating the original
multidict.MultiDictwhen creating a newmultidict.CIMultiDictfrom an existing one when keyword arguments are also passed – by @bdraco.Related issues and pull requests on GitHub: #1113.
Prevented crashing with a segfault when
repr()is called for recursive multidicts and their proxies and views.Related issues and pull requests on GitHub: #1115.
6.3.0¶
(2025-03-31)
Bug fixes¶
Set operations for
KeysViewandItemsViewof case-insensitive multidicts and their proxies are processed in case-insensitive manner.Related issues and pull requests on GitHub: #965.
Rewrote
multidict.CIMultiDictand it proxy to always returnmultidict.istrkeys.istris derived fromstr, thus the change is backward compatible.The performance boost is about 15% for some operations for C Extension, pure Python implementation have got a visible (15% - 230%) speedup as well.
Related issues and pull requests on GitHub: #1097.
Fixed a crash when extending a multidict from multidict proxy if C Extensions were used.
Related issues and pull requests on GitHub: #1100.
Features¶
Implemented a custom parser for
METH_FASTCALL | METH_KEYWORDSprotocol – by @asvetlov.The patch re-enables fast call protocol in the
multidictC Extension.Speedup is about 25%-30% for the library benchmarks for Python 3.12+.
Related issues and pull requests on GitHub: #1070.
The C-extension no longer pre-allocates a Python exception object in lookup-related methods of
MultiDictwhen the passed-in key is not found but default value is provided.Namely, this affects
MultiDict.getone(),MultiDict.getall(),MultiDict.get(),MultiDict.pop(),MultiDict.popone(), andMultiDict.popall().Additionally, the
MultiDictcomparison with regulardictionaries is now about 60% faster on Python 3.13+ in the fallback-to-default case.Related issues and pull requests on GitHub: #1078.
Implemented
__repr__()for C Extension classes in C.The speedup is about 2.5 times.
Related issues and pull requests on GitHub: #1081.
Made C version of
multidict.istrpickleable.Related issues and pull requests on GitHub: #1098.
Optimized multidict creation and extending / updating if C Extensions are used.
The speedup is between 25% and 70% depending on the usage scenario.
Related issues and pull requests on GitHub: #1101.
multidict.MultiDict.popitem()is changed to remove the latest entry instead of the first.It gives O(1) amortized complexity.
The standard
dict.popitem()removes the last entry also.Related issues and pull requests on GitHub: #1105.
Contributor-facing changes¶
Started running benchmarks for the pure Python implementation in addition to the C implementation – by @bdraco.
Related issues and pull requests on GitHub: #1092.
The the project-wide Codecov metric is no longer reported via GitHub Checks API. The combined value is not very useful because one of the sources (MyPy) cannot reach 100% with the current state of the ecosystem. We may want to reconsider in the future. Instead, we now have two separate “runtime coverage” metrics for library code and tests. They are to be kept at 100% at all times. And the “type coverage” metric will remain advisory, at a lower threshold.
The default patch metric check is renamed to “runtime” to better reflect its semantics. This one will also require 100% coverage. Another “typing” patch coverage metric is now reported alongside it. It’s considered advisory, just like its project counterpart.
When looking at Codecov, one will likely want to look at MyPy and pytest flags separately. It is usually best to avoid looking at the PR pages that sometimes display combined coverage incorrectly.
The change additionally disables the deprecated GitHub Annotations integration in Codecov.
Finally, the badge coloring range now starts at 100%.
– by @webknjaz
Related issues and pull requests on GitHub: #1093.
Miscellaneous internal changes¶
Synchronized
pythoncapi_compat.hwith the latest available version.Related issues and pull requests on GitHub: #1063.
Moved registering ABCs for C Extension classes from C to Python.
Related issues and pull requests on GitHub: #1083.
Refactored the internal
pair_listimplementation.Related issues and pull requests on GitHub: #1084.
Implemented views comparison and disjoints in C instead of Python helpers.
The performance boost is about 40%.
Related issues and pull requests on GitHub: #1096.
6.2.0¶
(2025-03-17)
Bug fixes¶
Features¶
Implemented support for the free-threaded build of CPython 3.13 – by @lysnikolaou.
Related issues and pull requests on GitHub: #1015.
Packaging updates and notes for downstreams¶
Started publishing wheels made for the free-threaded build of CPython 3.13 – by @lysnikolaou.
Related issues and pull requests on GitHub: #1015.
Miscellaneous internal changes¶
Used stricter typing across the code base, resulting in improved typing accuracy across multidict classes. Funded by an
NLnetgrant.Related issues and pull requests on GitHub: #1046.
6.1.0 (2024-09-09)¶
Bug fixes¶
Covered the unreachable code path in
multidict._multidict_base._abc_itemsview_register()with typing – by @skinnyBat.Related issues and pull requests on GitHub: #928.
Features¶
Removals and backward incompatible breaking changes¶
Contributor-facing changes¶
Added tests to have full code coverage of the
multidict._multidict_base._viewbaseset_richcmp()function – by @skinnyBat.Related issues and pull requests on GitHub: #928.
The deprecated
::set-outputworkflow command has been replaced by the$GITHUB_OUTPUTenvironment variable in the GitHub Actions CI/CD workflow definition.Related issues and pull requests on GitHub: #940.
codecov-action has been temporarily downgraded to
v3in the GitHub Actions CI/CD workflow definitions in order to fix uploading coverage to Codecov. See this issue for more details.Related issues and pull requests on GitHub: #941.
In the GitHub Actions CI/CD workflow definition, the
Get pip cache dirstep has been fixed for Windows runners by addingshell: bash. See actions/runner#2224 for more details.Related issues and pull requests on GitHub: #942.
Interpolation of the
pipcache keys has been fixed by adding missing$syntax in the GitHub Actions CI/CD workflow definition.Related issues and pull requests on GitHub: #943.
6.0.5 (2024-02-01)¶
Bug fixes¶
Upgraded the C-API macros that have been deprecated in Python 3.9 and later removed in 3.13 – by @iemelyanov.
Related issues and pull requests on GitHub: #862, #864, #868, #898.
Reverted to using the public argument parsing API
PyArg_ParseTupleAndKeywords()under Python 3.12 – by @charles-dyfis-net and @webknjaz.The effect is that this change prevents build failures with clang 16.9.6 and gcc-14 reported in #926. It also fixes a segmentation fault crash caused by passing keyword arguments to
MultiDict.getall()discovered by @jonaslb and @hroncok while examining the problem.Related issues and pull requests on GitHub: #862, #909, #926, #929.
Fixed a
SystemError: null argument to internal routineerror on aMultiDict.items().isdisjoint()call when using C Extensions.Related issues and pull requests on GitHub: #927.
Improved documentation¶
On the Contributing docs page, a link to the
Towncrier philosophyhas been fixed.Related issues and pull requests on GitHub: #911.
Packaging updates and notes for downstreams¶
Stopped marking all files as installable package data – by @webknjaz.
This change helps
setuptoolsunderstand that C-headers are not to be installed underlib/python3.x/site-packages/.Related commits on GitHub: 31e1170.
Started publishing pure-python wheels to be installed as a fallback – by @webknjaz.
Related commits on GitHub: 7ba0e72.
Switched from
setuptools’ legacy backend (setuptools.build_meta:__legacy__) to the modern one (setuptools.build_meta) by actually specifying the the[build-system] build-backendoption inpyproject.toml– by @Jackenmen.Related issues and pull requests on GitHub: #802.
Declared Python 3.12 supported officially in the distribution package metadata – by @hugovk.
Related issues and pull requests on GitHub: #877.
Contributor-facing changes¶
The test framework has been refactored. In the previous state, the circular imports reported in #837 caused the C-extension tests to be skipped.
Now, there is a set of the
pytestfixtures that is set up in a parametrized manner allowing to have a consistent way of accessing mirroredmultidictimplementations across all the tests.This change also implemented a pair of CLI flags (
--c-extensions/--no-c-extensions) that allow to explicitly request deselecting the tests running against the C-extension.– by @webknjaz.
Related issues and pull requests on GitHub: #98, #837, #915.
Updated the test pins lockfile used in the
cibuildwheeltest stage – by @hoodmane.Related issues and pull requests on GitHub: #827.
Added an explicit
voidfor arguments in C-function signatures which addresses the following compiler warning:warning: a function declaration without a prototype is deprecated in all versions of C [-Wstrict-prototypes]– by @hoodmane
Related issues and pull requests on GitHub: #828.
An experimental Python 3.13 job now runs in the CI – @webknjaz.
Related issues and pull requests on GitHub: #920.
Added test coverage for the and, or,
sub, andxoroperators in themultidict/_multidict_base.pymodule. It also coversNotImplementedand “Iterable-but-not-Set” cases there.– by @a5r0n
Related issues and pull requests on GitHub: #936.
The version of pytest is now capped below 8, when running MyPy against Python 3.7. This pytest release dropped support for said runtime.
Related issues and pull requests on GitHub: #937.
6.0.4 (2022-12-24)¶
Bugfixes¶
Fixed a type annotations regression introduced in v6.0.2 under Python versions <3.10. It was caused by importing certain types only available in newer versions. (#798)
6.0.3 (2022-12-03)¶
Features¶
6.0.2 (2022-01-24)¶
Bugfixes¶
6.0.1 (2022-01-23)¶
Bugfixes¶
Restored back
MultiDict,CIMultiDict,MultiDictProxy, andCIMutiDictProxygeneric type arguments; they are parameterized by value type, but the key type is fixed by container class.MultiDict[int]meansMutableMultiMapping[str, int]. The key type ofMultiDictis alwaysstr, while all str-like keys are accepted by API and converted tostrinternally.The same is true for
CIMultiDict[int]which meansMutableMultiMapping[istr, int]. str-like keys are accepted but converted toistrinternally. (#682)
6.0.0 (2022-01-22)¶
Features¶
Use
METH_FASTCALLwhere it makes sense.MultiDict.add()is 2.2 times faster now,CIMultiDict.add()is 1.5 times faster. The same boost is applied toget*(),setdefault(), andpop*()methods. (#681)
Bugfixes¶
Deprecations and Removals¶
Dropped Python 3.6 support (#680)
Misc¶
5.2.0 (2021-10-03)¶
Features¶
Added support Python 3.10
Started shipping platform-specific wheels with the
musltag targeting typical Alpine Linux runtimes.Started shipping platform-specific arm64 wheels for Apple Silicon. (#629)
Bugfixes¶
Fixed pure-python implementation that used to raise “Dictionary changed during iteration” error when iterated view (
.keys(),.values()or.items()) was created before the dictionary’s content change. (#620)
5.1.0 (2020-12-03)¶
Features¶
Supported
GenericAliases(MultiDict[str]) for Python 3.9+ #553
Bugfixes¶
Synchronized the declared supported Python versions in
setup.pywith actually supported and tested ones. #552
5.0.1 (2020-11-14)¶
Bugfixes¶
Provided x86 Windows wheels #550
5.0.0 (2020-10-12)¶
Features¶
Removal¶
Dropped Python 3.5 support; Python 3.6 is the minimal supported Python version.
Misc¶
4.7.6 (2020-05-15)¶
Bugfixes¶
Fixed an issue with some versions of the
wheeldist failing because of being unable to detect the license file. #481
4.7.5 (2020-02-21)¶
Bugfixes¶
Fixed creating and updating of
MultiDictfrom a sequence of pairs and keyword arguments. Previously passing a list argument modified it inplace, and other sequences caused an error. #457Fixed comparing with mapping: an exception raised in the
__len__()method caused raising a SyntaxError. #459Fixed comparing with mapping: all exceptions raised in the
__getitem__()method were silenced. #460
4.7.4 (2020-01-11)¶
Bugfixes¶
Multidict 4.7.3 (2019-12-30)¶
Features¶
Bugfixes¶
Fix crashes in
popone/popallwhen default is returned. #450
Improved Documentation¶
Corrected the documentation for
MultiDict.extend()#446
4.7.2 (2019-12-20)¶
Bugfixes¶
Fixed crashing when multidict is used pyinstaller #432
Fixed typing for
CIMultiDict.copy()#434Fixed a memory leak in
MultiDict.copy()#443
4.7.1 (2019-12-12)¶
Bugfixes¶
CIMultiDictProxy.copy()fixed to return a case-insensitivemultidict._multidict.CIMultiDict()object. #427Made
CIMultiDictsubclassable again. #416Fixed a regression,
multidict.MultiDictcan be constructed from an arbitrary iterable of pairs again. #418CIMultiDict.add()may be called with keyword arguments now. #421
Improved Documentation¶
4.7.0 (2019-12-10)¶
Features¶
Replace Cython optimization with pure C #249
Implement
__length_hint__()for iterators #310Support the MultiDict[str] generic specialization in the runtime. #392
Embed pair_list_t structure into MultiDict Python object #395
Embed multidict pairs for small dictionaries to amortize the memory usage. #396
Support weak references to C Extension classes. #399
Add docstrings to provided classes. #400
Merge
multidict._istrback withmultidict._multidict. #409
Bugfixes¶
4.6.1 (2019-11-21)¶
Bugfixes¶
Fix PyPI link for GitHub Issues badge. #391
4.6.0 (2019-11-20)¶
Bugfixes¶
4.5.2 (2018-11-28)¶
Fix another memory leak introduced by 4.5.0 release #307
4.5.1 (2018-11-22)¶
Fix a memory leak introduced by 4.5.0 release #306
4.5.0 (2018-11-19)¶
Multidict views ported from Cython to C extension #275
4.4.2 (2018-09-19)¶
Restore Python 3.4 support #289
4.4.1 (2018-09-17)¶
4.4.0 (2018-07-04)¶
Rewrite C implementation to use C pair list.
Fix update order when both
argandkwargsare used.
4.3.1 (2018-05-06)¶
Fix a typo in multidict stub file.
4.3.0 (2018-05-06)¶
Polish type hints, make multidict type definitions generic.
4.2.0 (2018-04-15)¶
Publish
py.typedflag for type hinting analyzers (mypyetc).
4.1.0 (2018-01-28)¶
Fix key casing in Pure Python implementation of
CIMultiDict#202
4.0.0 (2018-01-14)¶
Started accepting multiple keys in
MultiDict.update()andCIMultiDict.update(). #199
3.3.2 (2017-11-02)¶
Fix tarball (again)
3.3.1 (2017-11-01)¶
Include .c files in tarball #181
3.3.0 (2017-10-15)¶
3.2.0 (2017-09-17)¶
Fix pickling #134
Fix equality check when other contains more keys #124
Fix
CIMultiDictcopy #107
3.1.3 (2017-07-14)¶
Fix build
3.1.2 (2017-07-14)¶
Fix type annotations
3.1.1 (2017-07-09)¶
3.1.0 (2017-06-25)¶
Raise
RuntimeErrorondictiterations if the dict was changed (#99)Update
__init__.pyisignatures
3.0.0 (2017-06-21)¶
Refactor internal data structures: main dict operations are about 100% faster now.
Preserve order on multidict updates
Updates are
md[key] = valandmd.update(...)calls.Now the last entry is replaced with new key/value pair, all previous occurrences are removed.
If key is not present in dictionary the pair is added to the end
Implement
.popall(key[, default])#84Implement dict’s version #86
Proxies are not pickable anymore #77
2.1.7 (2017-05-29)¶
Fix import warning on Python 3.6 #79
2.1.6 (2017-05-27)¶
Rebuild the library for fixing missing
__spec__attribute #79
2.1.5 (2017-05-13)¶
Build Python 3.6 binary wheels
2.1.4 (2016-12-1)¶
Remove
LICENSEfilename extension @MANIFEST.infile #31
2.1.3 (2016-11-26)¶
Add a fastpath for multidict extending by multidict
2.1.2 (2016-09-25)¶
Fixed
CIMultiDict.update()for case of acceptingistr.
2.1.1 (2016-09-22)¶
Fixed the
CIMultiDictconstructor for the case of acceptingistr. #11
2.1.0 (2016-09-18)¶
Allow to create proxy from proxy
Add type hints (PEP 484)
2.0.1 (2016-08-02)¶
Don’t crash on
{} - MultiDict().keys()and similar operations #6
2.0.0 (2016-07-28)¶
Switch from uppercase approach for case-insensitive string to
str.title(). #5Deprecate
multidict.upstr()class in favor ofistralias.
1.2.2 (2016-08-02)¶
Don’t crash on
{} - MultiDict().keys()and similar operations #6
1.2.1 (2016-07-21)¶
Don’t expose
multidict.__version__
1.2.0 (2016-07-16)¶
Make
upstr(upstr('abc'))much faster
1.1.0 (2016-07-06)¶
Fixed
CIMultiDict.pop(): it is case insensitive now. #1Provide manylinux wheels as well as Windows ones
1.0.3 (2016-03-24)¶
Add missing MANIFEST.in
1.0.2 (2016-03-24)¶
Fix setup build
1.0.0 (2016-02-19)¶
Initial implementation