NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
PyPI · #710 most downloaded on PyPI
The bidirectional mapping library for Python.
Last release 1 months ago
25 Aug 2026
Release timing varies
gaps range from 2 weeks to 2.5 years
Most releases are documented
notes for 35 of 39 stable releases
1 version withdrawn
withdrawn after publishing
12 years old
44 releases · first in 2014
Bidict is the bidirectional mapping library for Python.
Bidict is the bidirectional mapping library for Python.
If you or your organization depends on bidict, please consider sponsoring.
Please see https://bidict.readthedocs.io/en/v0.24.1/changelog.html for the notable changes in this release.
Fix the RECORD file in the published 0.24.0 wheel by upgrading to a fixed version of uv_build. 406
Fix a test failure on Python 3.15 caused by changes to ~collections.UserDict. 407
Bidict is the bidirectional mapping library for Python.
One column per quarter.
Bidict is the bidirectional mapping library for Python.
If you or your organization depends on bidict, please consider sponsoring.
Please see https://bidict.readthedocs.io/en/v0.24.0/changelog.html for the notable changes in this release.
Remove bidict.metadata and associated metadata from the bidict module (e.g. bidict.__version__). Use e.g. importlib.metadata.metadata("bidict")["Version"] instead.
Fix a bug where pickling or ~copy.deepcopying an instance of a dynamically-generated inverse class (see extending:Dynamic Inverse Class Generation) could change the order of its items. 398
Pickles written by bidict 0.23.1 and earlier can no longer be read. They call the private BidictBase._from_other() with an argument it no longer accepts, which was retained for no other purpose. Pickle compatibility across versions has never been guaranteed, and dropping it here keeps ~bidict.BidictBase.__reduce__ free of special cases.
Fix a bug where a non-ordered bidict's ~bidict.BidictBase.values view could yield its values in a different order than ~bidict.BidictBase.keys yields the corresponding keys, so that e.g. zip(b.keys(), b.values()) silently paired up the wrong keys and values.
Fix a bug where ~bidict.MutableBidict.putall and ~bidict.MutableBidict.update could leave earlier items inserted when a later item in a bulk update raised a non-duplication exception, rather than failing clean. 389
Fix a bug where a bulk update did not fail clean at all when the ~bidict.OnDup in effect contained no ~bidict.RAISE action – as with ~bidict.MutableBidict.forceupdate, ~bidict.MutableBidict.putall passed ~bidict.ON_DUP_DROP_OLD, or ~bidict.MutableBidict.update on a subclass that overrides ~bidict.BidictBase.on_dup (e.g. the YoloBidict recipe in extending). Rollback was previously enabled only when a duplication error was possible, but a bulk update can also fail while unpacking an item, hashing a key or value, or writing to a backing mapping. Rollback is now always enabled for these methods. 392
Fix a bug where a write or removal that a custom backing mapping refused could leave a custom bidict's two backing mappings out of sync, breaking the bidirectional invariant, rather than failing clean. 401 403
Fix a bug where mutating an ~bidict.OrderedBidict while iterating over it produced incorrect behavior rather than raising an error. 393
A bidict and its inverse now always refer to the same object for each contained key and value, rather than possibly to equivalent but distinct ones, so that e.g. b.inverse[b[key]] is key always holds. Writing an item whose key or value is equal to a contained one now keeps the object already contained, as dict does when a key is overwritten, instead of keeping one object in each direction. See also addendum:Equivalent but distinct :class:~collections.abc.Hashable`\s` 396
Fix a bug where setting an already-contained (key, value) pair spuriously raised ~bidict.KeyAndValueDuplicationError or AssertionError (rather than being a no-op, as documented) when the key or value has non-reflexive equality (e.g. nan) or asymmetric equality. 377
Fix a bug where set operations between an ~bidict.OrderedBidict's keys view and its items view (or vice versa) raised TypeError (or, for ==, returned the wrong result) rather than behaving like the equivalent plain dict views. 376
Single-item writes such as ~bidict.MutableBidict.__setitem__, ~bidict.MutableBidict.put, and ~bidict.MutableBidict.forceput are now ~6x faster: most of what they cost was never the write itself, but typing machinery being re-evaluated on every call. Iterating an ~bidict.OrderedBidict is also ~1.2x faster. Everything else is within a couple of percent of 0.23.1.
A bidict backed by a dict subclass now gets that mapping's own views from ~bidict.BidictBase.keys and ~bidict.BidictBase.items, as a bidict backed by an exact dict already did. Previously only an exact dict qualified, so such a bidict got generic views instead, which were not ~collections.abc.Reversible (even when the bidict itself was), had no .mapping attribute, and performed their set operations in Python rather than in C. This affects every backing mapping used in the recipes in extending, since collections.OrderedDict, collections.defaultdict, and sortedcontainers.SortedDict are all dict subclasses.
Fix a bug where a subclass of a bidict class whose backing mappings are not ~collections.abc.Reversible could not itself be reversible, even when it specified backing mappings that are.
Fix a bug where an ~bidict.OrderedBidictBase that is not an ~bidict.OrderedBidict could yield its items in the wrong order from ~bidict.OrderedBidictBase.keys, ~bidict.OrderedBidictBase.items, ~bidict.BidictBase.values, repr, and ~bidict.BidictBase.equals_order_sensitive.
Remove bidict.metadata and associated metadata from the bidict module (e.g. bidict.version ). Use e.g. importlib.metadata.metadata("bidict")["Version"] instead.
Fix a bug where pickling or deepcopy() ing an instance of a dynamically-generated inverse class (see Dynamic Inverse Class Generation ) could change the order of its items. #398
Pickles written by bidict 0.23.1 and earlier can no longer be read. They call the private BidictBase._from_other() with an argument it no longer accepts, which was retained for no other purpose. Pickle compatibility across versions has never been guaranteed , and dropping it here keeps reduce() free of special cases.
Fix a bug where a non-ordered bidict’s values() view could yield its values in a different order than keys() yields the corresponding keys, so that e.g. zip(b.keys(), b.values()) silently paired up the wrong keys and values.
Fix a bug where putall() and update() could leave earlier items inserted when a later item in a bulk update raised a non-duplication exception, rather than failing clean. #389
Fix a bug where a bulk update did not fail clean at all when the OnDup in effect contained no RAISE action – as with forceupdate() , putall() passed ON_DUP_DROP_OLD , or update() on a subclass that overrides on_dup (e.g. the YoloBidict recipe in Extending bidict ). Rollback was previously enabled only when a duplication error was possible, but a bulk update can also fail while unpacking an item, hashing a key or value, or writing to a backing mapping. Rollback is now always enabled for these methods. #392
Fix a bug where a write or removal that a custom backing mapping refused could leave a custom bidict’s two backing mappings out of sync, breaking the bidirectional invariant, rather than failing clean. #401 #403
Fix a bug where mutating an OrderedBidict while iterating over it produced incorrect behavior rather than raising an error. #393
A bidict and its inverse now always refer to the same object for each contained key and value, rather than possibly to equivalent but distinct ones, so that e.g. b.inverse[b[key]] is key always holds. Writing an item whose key or value is equal to a contained one now keeps the object already contained, as dict does when a key is overwritten, instead of keeping one object in each direction. See also Equivalent but distinct Hashables #396
Fix a bug where setting an already-contained (key, value) pair spuriously raised KeyAndValueDuplicationError or AssertionError (rather than being a no-op, as documented) when the key or value has non-reflexive equality (e.g. nan ) or asymmetric equality. #377
Fix a bug where set operations between an OrderedBidict ’s keys view and its items view (or vice versa) raised TypeError (or, for == , returned the wrong result) rather than behaving like the equivalent plain dict views. #376
Single-item writes such as setitem() , put() , and forceput() are now ~6x faster: most of what they cost was never the write itself, but typing machinery being re-evaluated on every call. Iterating an OrderedBidict is also ~1.2x faster. Everything else is within a couple of percent of 0.23.1.
A bidict backed by a dict subclass now gets that mapping’s own views from keys() and items() , as a bidict backed by an exact dict already did. Previously only an exact dict qualified, so such a bidict got generic views instead, which were not Reversible (even when the bidict itself was), had no .mapping attribute, and performed their set operations in Python rather than in C. This affects every backing mapping used in the recipes in Extending bidict , since collections.OrderedDict , collections.defaultdict , and sortedcontainers.SortedDict are all dict subclasses.
Fix a bug where a subclass of a bidict class whose backing mappings are not Reversible could not itself be reversible, even when it specified backing mappings that are.
Fix a bug where an OrderedBidictBase that is not an OrderedBidict could yield its items in the wrong order from keys() , items() , values() , repr() , and equals_order_sensitive() .
Bidict is the bidirectional mapping library for Python.
Bidict is the bidirectional mapping library for Python.
If you or your organization depends on bidict, please consider sponsoring.
Please see https://bidict.readthedocs.io/en/v0.23.1/changelog.html for the notable changes in this release.
Fix a regression in 0.23.0 that could defeat type inference of a bidict's key type and value type when running in Python 3.8 or 3.9. 310
Bidict is the bidirectional mapping library for Python.
Bidict is the bidirectional mapping library for Python.
If you or your organization depends on bidict, please consider sponsoring.
Please see https://bidict.readthedocs.io/en/v0.23.0/changelog.html for the notable changes in this release.
Primarily, this release simplifies bidict by removing minor features that are no longer necessary or that have little to no apparent usage, and it also includes some performance optimizations.
Specifically, initializing or updating a bidict is now up to 70% faster in microbenchmarks.
The changes in this release will also make it easier to maintain and improve bidict in the future, including further potential performance optimizations.
It also contains several other improvements.
Drop support for Python 3.7, which reached end of life on 2023-06-27, and take advantage of features available in Python 3.8+.
Remove FrozenOrderedBidict now that Python 3.7 is no longer supported. ~bidict.frozenbidict now provides everything that FrozenOrderedBidict provided (including reversibility) on all supported Python versions, but with less space overhead.
Remove namedbidict due to low usage.
Remove the kv field of ~bidict.OnDup which specified the ~bidict.OnDupAction to take in the case of basic-usage:key and value duplication. The ~bidict.OnDup.val field now specifies the action to take in the case of basic-usage:key and value duplication as well as just value duplication.
Improve type hints for the ~bidict.BidictBase.inv shortcut alias for ~bidict.BidictBase.inverse.
Fix a bug where calls like bidict(None), bi.update(False), etc. would fail to raise a TypeError.
All ~bidict.BidictBase.__init__, ~bidict.MutableBidict.update, and related methods now handle SupportsKeysAndGetItem objects that are not ~collections.abc.Mappings the same way that MutableMapping.update() does, before falling back to handling the provided object as an iterable of pairs.
The repr of ordered bidicts now matches that of regular bidicts, e.g. OrderedBidict({1: 1}) rather than OrderedBidict([(1, 1)]).
(Accordingly, the bidict.__repr_delegate__ field has been removed now that it's no longer needed.)
This tracks with the change to collections.OrderedDict's repr in Python 3.12.
Test with Python 3.12 in CI.
Note: Older versions of bidict also support Python 3.12, even though they don't explicitly declare support for it.
Drop use of Trove classifiers that declare support for specific Python versions in package metadata.
Bidict is the bidirectional mapping library for Python.
Bidict is the bidirectional mapping library for Python.
If you or your organization depends on bidict, please consider sponsoring bidict on GitHub.
Please see https://bidict.readthedocs.io/en/v0.22.1/changelog.html for the notable changes in this release.
Only include the source code in the source distribution. This reduces the size of the source distribution from ~200kB to ~30kB.
Fix the return type hint of bidict.inverted to return an ~collections.abc.Iterator, rather than an ~collections.abc.Iterable.
Bidict is the bidirectional mapping library for Python. If you or your organization depends on bidict, please consider sponsoring bidict on GitHub .
Bidict is the bidirectional mapping library for Python.
If you or your organization depends on bidict, please consider sponsoring bidict on GitHub.
Please see https://bidict.readthedocs.io/en/v0.22.0/changelog.html for the notable changes in this release.
Drop support for Python 3.6, which reached end of life on 2021-12-23 and is no longer supported by pip as of pip version 22. Take advantage of this to reduce bidict's maintenance costs.
Use mypy-appeasing explicit re-exports in __init__.py (e.g. import x as x) so that mypy no longer gives you an implicit re-export error if you run it with --no-implicit-reexport (or --strict) against code that imports from bidict.
Update the implementations and type annotations of bidict.BidictBase.keys and bidict.BidictBase.values to make use of the new ~bidict.BidictKeysView type, which works a bit better with type checkers.
Inverse bidict instances are now computed lazily the first time the ~bidict.BidictBase.inverse attribute is accessed rather than being computed eagerly during initialization. (A bidict's backing, inverse, one-way mapping is still kept in sync eagerly as any mutations are made, to preserve key- and value-uniqueness.)
Optimize initializing a bidict with another bidict. In a microbenchmark on Python 3.10, this now performs over 2x faster.
Optimize updating an empty bidict with another bidict. In a microbenchmark on Python 3.10, this now performs 60-75% faster.
Optimize ~bidict.BidictBase.copy. In a microbenchmark on Python 3.10, this now performs 10-20x faster.
Optimize rolling back failed updates to a bidict in the case that the number of items passed to the update call can be determined to be larger than the bidict being updated. Previously this rollback was O(n) in the number of items passed. Now it is O(1), i.e. unboundedly faster.
Optimize bidict.BidictBase.__contains__ (the method called when you run key in mybidict). In a microbenchmark on Python 3.10, this now performs over 3-10x faster in the False case, and at least 50% faster in the True case.
Optimize bidict.BidictBase.__eq__ (the method called when you run mybidict == other). In a microbenchmark on Python 3.10, this now performs 15-25x faster for ordered bidicts, and 7-12x faster for unordered bidicts.
Optimize ~bidict.BidictBase.equals_order_sensitive. In a microbenchmark on Python 3.10, this now performs 2x faster for ordered bidicts and 60-90% faster for unordered bidicts.
Optimize the ~collections.abc.MappingView objects returned by bidict.OrderedBidict.keys, bidict.OrderedBidict.values, and bidict.OrderedBidict.items to delegate to backing dict_keys and dict_items objects if available, which are much faster in CPython. For example, in a microbenchmark on Python 3.10, orderedbi.items() == d.items() now performs 30-50x faster.
Fix a bug where bidict.BidictBase.__eq__ was always returning False rather than NotImplemented in the case that the argument was not a ~collections.abc.Mapping, defeating the argument's own __eq__() if implemented. As a notable example, bidicts now correctly compare equal to unittest.mock.ANY.
bidict.BidictBase now adds a __reversed__ implementation to subclasses that don't have an overridden implementation depending on whether both their backing mappings are ~collections.abc.Reversible. Previously, a __reversed__ implementation was only added to ~bidict.BidictBase when BidictBase._fwdm_cls was ~collections.abc.Reversible. So if a ~bidict.BidictBase subclass set its _fwdm_cls to a non-reversible mutable mapping, it would also have to manually set its __reversed__ attribute to None to override the implementation inherited from ~bidict.BidictBase. This is no longer necessary thanks to bidict's new object.__init_subclass__ logic.
The ~collections.abc.MappingView objects returned by bidict.OrderedBidict.keys, bidict.OrderedBidict.values, and bidict.OrderedBidict.items are now ~collections.abc.Reversible. (This was already the case for unordered bidicts when running on Python 3.8+.)
Add support for Python 3.9-style dict merge operators (PEP 584).
See the tests for examples.
Update docstrings for bidict.BidictBase.keys, bidict.BidictBase.values, and bidict.BidictBase.items to include more details.
namedbidict now exposes the passed-in keyname and valname in the corresponding properties on the generated class.
namedbidict now requires base_type to be a subclass of ~bidict.BidictBase, but no longer requires base_type to provide an _isinv attribute, which ~bidict.BidictBase subclasses no longer provide.
When attempting to pickle a bidict's inverse whose class was dynamically generated, and no reference to the dynamically-generated class has been stored anywhere in sys.modules where pickle can find it, the pickle call is now more likely to succeed rather than failing with a ~pickle.PicklingError.
Remove the use of slots from (non-ABC) bidict types.
This better matches the mapping implementations in Python's standard library, and significantly reduces code complexity and maintenance burden. The memory savings conferred by using slots are not noticeable unless you're creating millions of bidict instances anyway, which is an extremely unusual usage pattern.
Of course, bidicts can still contain millions (or more) items (which is not an unusual usage pattern) without using any more memory than before these changes. Notably, slots are still used in the internal linked list nodes of ordered bidicts to save memory, since as many node instances are created as there are items inserted.
Please see https://bidict.readthedocs.io/en/v0.21.4/changelog.html#id1 for the changes in this release.
Please see https://bidict.readthedocs.io/en/v0.21.4/changelog.html#id1 for the changes in this release.
Explicitly declare support for Python 3.10 as well as some minor internal improvements.
Please see https://bidict.readthedocs.io/en/v0.21.3/changelog.html#id1 for the changes in this release.
Please see https://bidict.readthedocs.io/en/v0.21.3/changelog.html#id1 for the changes in this release.
All bidicts now provide the ~bidict.BidictBase.equals_order_sensitive method, not just ~bidict.OrderedBidicts.
Since support for Python < 3.6 was dropped in v0.21.0, dicts provide a deterministic ordering on all supported Python versions, and as a result, all bidicts do too. So now even non-Ordered bidicts might as well provide ~bidict.BidictBase.equals_order_sensitive.
See the updated other-bidict-types:What about order-preserving dicts? docs for more info.
Take better advantage of the fact that dicts became reversible in Python 3.8.
Specifically, now even non-Ordered bidicts provide a ~bidict.BidictBase.__reversed__ implementation on Python 3.8+ that calls reversed on the backing _fwdm mapping.
As a result, if you are using Python 3.8+, ~bidict.frozenbidict now gives you everything that FrozenOrderedBidict gives you, but with less space overhead.
Drop setuptools_scm as a setup_requires dependency.
Remove the bidict.__version_info__ attribute.
All bidicts now provide the equals_order_sensitive() method, not just OrderedBidict s.
Since support for Python < 3.6 was dropped in v0.21.0, dict s provide a deterministic ordering on all supported Python versions, and as a result, all bidicts do too. So now even non- Ordered bidicts might as well provide equals_order_sensitive() .
See the updated What about order-preserving dicts? docs for more info.
Take better advantage of the fact that dicts became reversible in Python 3.8.
Specifically, now even non- Ordered bidicts provide a reversed() implementation on Python 3.8+ that calls reversed() on the backing _fwdm mapping.
As a result, if you are using Python 3.8+, frozenbidict now gives you everything that FrozenOrderedBidict gives you, but with less space overhead.
Drop setuptools_scm as a setup_requires dependency.
Remove the bidict.version_info attribute.
Please see https://bidict.readthedocs.io/en/v0.21.2/changelog.html for the changes in this release.
Please see https://bidict.readthedocs.io/en/v0.21.2/changelog.html for the changes in this release.
This release was yanked and replaced with the 0.21.2 release, which actually provides the intended changes.
This release was yanked and replaced with the 0.21.2 release, which actually provides the intended changes.
Please see https://bidict.readthedocs.io/en/v0.21.0/changelog.html for the changes in this release.
Please see https://bidict.readthedocs.io/en/v0.21.0/changelog.html for the changes in this release.
bidict now provides type hints! ⌨️ ✅
Adding type hints to bidict poses particularly interesting challenges due to the combination of generic types, dynamically-generated types (such as inverse bidict classes and namedbidicts), and complicating optimizations such as the use of slots and weakrefs.
It didn't take long to hit bugs and missing features in the state of the art for type hinting in Python today, e.g. missing higher-kinded types support (python/typing#548), too-narrow type hints for collections.abc.Mapping (python/typeshed#4435), a typing.Generic bug in Python 3.6 (BPO-41451), etc.
That said, this release should provide a solid foundation for code using bidict that enables static type checking.
As always, if you spot any opportunities to improve bidict (including its new type hints), please don't hesitate to submit a PR!
Add bidict.MutableBidirectionalMapping ABC.
The other-bidict-types:Bidict Types Diagram has been updated accordingly.
Drop support for Python 3.5, which reaches end of life on 2020-09-13, represents a tiny percentage of bidict downloads on PyPI Stats, and lacks support for variable type hint syntax, ordered dicts, and object.__init_subclass__.
Remove the no-longer-needed bidict.compat module.
Move inverse bidict class access from a property to an attribute set in ~bidict.BidictBase.__init_subclass__, to save function call overhead on repeated access.
bidict.OrderedBidictBase.__iter__ no longer accepts a reverse keyword argument so that it matches the signature of container.__iter__.
Set the __module__ attribute of various bidict types (using sys._getframe when necessary) so that private, internal modules are not exposed e.g. in classes' repr strings.
namedbidict now immediately raises TypeError if the provided base_type does not provide _isinv or ~object.__getstate__, rather than succeeding with a class whose instances may raise AttributeError when these attributes are accessed.
Please see https://bidict.readthedocs.io/en/v0.20.0/changelog.html for the changes in this release.
Please see https://bidict.readthedocs.io/en/v0.20.0/changelog.html for the changes in this release.
The following breaking changes are expected to affect few if any users.
Remove APIs deprecated in the previous release:
bidict.OVERWRITE and bidict.IGNORE.
The on_dup_key, on_dup_val, and on_dup_kv arguments of ~bidict.MutableBidict.put and ~bidict.MutableBidict.putall.
The on_dup_key, on_dup_val, and on_dup_kv ~bidict.bidict class attributes.
Remove bidict.BidirectionalMapping.__subclasshook__ due to lack of use and maintenance cost.
Fixes a bug introduced in 0.15.0 that caused any class with an inverse attribute to be incorrectly considered a subclass of collections.abc.Mapping. 111
Please see https://bidict.readthedocs.io/en/v0.19.0/changelog.html for the changes in this release.
Please see https://bidict.readthedocs.io/en/v0.19.0/changelog.html for the changes in this release.
Drop support for Python 2 as promised in v0.18.2.
The bidict.compat module has been pruned accordingly.
This makes bidict more efficient on Python 3 and enables further improvement to bidict in the future.
Deprecate bidict.OVERWRITE and bidict.IGNORE. A UserWarning will now be emitted if these are used.
bidict.DROP_OLD and bidict.DROP_NEW should be used instead.
Rename DuplicationPolicy to ~bidict.OnDupAction (and implement it via an ~enum.Enum).
An ~bidict.OnDupAction may be one of ~bidict.RAISE, ~bidict.DROP_OLD, or ~bidict.DROP_NEW.
Expose the new ~bidict.OnDup class to contain the three ~bidict.OnDupActions that should be taken upon encountering the three kinds of duplication that can occur (key, val, kv).
Provide the ~bidict.ON_DUP_DEFAULT, ~bidict.ON_DUP_RAISE, and ~bidict.ON_DUP_DROP_OLD ~bidict.OnDup convenience instances.
Deprecate the on_dup_key, on_dup_val, and on_dup_kv arguments of ~bidict.MutableBidict.put and ~bidict.MutableBidict.putall. A UserWarning will now be emitted if these are used.
These have been subsumed by the new on_dup argument, which takes an ~bidict.OnDup instance.
Use it like this: bi.put(1, 2, OnDup(key=RAISE, val=...)). Or pass one of the instances already provided, such as ~bidict.ON_DUP_DROP_OLD. Or just don't pass an on_dup argument to use the default value of ~bidict.ON_DUP_RAISE.
The basic-usage:Values Must Be Unique docs have been updated accordingly.
Deprecate the on_dup_key, on_dup_val, and on_dup_kv ~bidict.bidict class attributes. A UserWarning will now be emitted if these are used.
These have been subsumed by the new ~bidict.BidictBase.on_dup class attribute, which takes an ~bidict.OnDup instance.
See the updated extending docs for example usage.
Improve the more efficient implementations of bidict.BidirectionalMapping.keys, bidict.BidirectionalMapping.values, and bidict.BidirectionalMapping.items, and now also provide a more efficient implementation of bidict.BidirectionalMapping.__iter__ by delegating to backing dicts in the bidict types for which this is possible.
Move bidict.BidictBase.values to bidict.BidirectionalMapping.values, since the implementation is generic.
No longer use __all__ in bidict's __init__.py.
Drop support for Python 2 as promised in v0.18.2 .
The bidict.compat module has been pruned accordingly.
This makes bidict more efficient on Python 3 and enables further improvement to bidict in the future.
Deprecate bidict.OVERWRITE and bidict.IGNORE . A UserWarning will now be emitted if these are used.
bidict.DROP_OLD and bidict.DROP_NEW should be used instead.
Rename DuplicationPolicy to OnDupAction (and implement it via an Enum ).
An OnDupAction may be one of RAISE , DROP_OLD , or DROP_NEW .
Expose the new OnDup class to contain the three OnDupAction s that should be taken upon encountering the three kinds of duplication that can occur ( key , val , kv ).
Provide the ON_DUP_DEFAULT , ON_DUP_RAISE , and ON_DUP_DROP_OLD OnDup convenience instances.
Deprecate the on_dup_key , on_dup_val , and on_dup_kv arguments of put() and putall() . A UserWarning will now be emitted if these are used.
These have been subsumed by the new on_dup argument, which takes an OnDup instance.
Use it like this: bi.put(1, 2, OnDup(key=RAISE, val=...)) . Or pass one of the instances already provided, such as ON_DUP_DROP_OLD . Or just don’t pass an on_dup argument to use the default value of ON_DUP_RAISE .
The Values Must Be Unique docs have been updated accordingly.
Deprecate the on_dup_key , on_dup_val , and on_dup_kv bidict class attributes. A UserWarning will now be emitted if these are used.
These have been subsumed by the new on_dup class attribute, which takes an OnDup instance.
See the updated Extending bidict docs for example usage.
Improve the more efficient implementations of bidict.BidirectionalMapping.keys , bidict.BidirectionalMapping.values , and bidict.BidirectionalMapping.items , and now also provide a more efficient implementation of bidict.BidirectionalMapping.iter by delegating to backing dict s in the bidict types for which this is possible.
Move bidict.BidictBase.values() to bidict.BidirectionalMapping.values , since the implementation is generic.
No longer use all in bidict ’s init.py .
Please see https://bidict.readthedocs.io/en/v0.18.4/changelog.html#id1 for the changes in this release.
Please see https://bidict.readthedocs.io/en/v0.18.4/changelog.html#id1 for the changes in this release.
Backport fix from v0.20.0 that removes bidict.BidirectionalMapping.__subclasshook__ due to lack of use and maintenance cost.
Please see https://bidict.readthedocs.io/en/v0.18.3/changelog.html for the changes in this release.
Please see https://bidict.readthedocs.io/en/v0.18.3/changelog.html for the changes in this release.
Improve validation of names passed to namedbidict: Use str.isidentifier on Python 3, and a better regex on Python 2.
On Python 3, set ~definition.__qualname__ on namedbidict classes based on the provided typename argument.
Please see https://bidict.readthedocs.io/en/v0.18.2/changelog.html for the changes in this release.
Please see https://bidict.readthedocs.io/en/v0.18.2/changelog.html for the changes in this release.
Warn that Python 2 support will be dropped in a future release when Python 2 is detected.
Please see https://bidict.readthedocs.io/en/v0.18.1/changelog.html for the changes in this release.
Please see https://bidict.readthedocs.io/en/v0.18.1/changelog.html for the changes in this release.
Fix a regression introduced by the memory optimizations added in 0.15.0 which caused deepcopied and unpickled bidicts to have their inverses set incorrectly. 94
Please see https://bidict.readthedocs.io/en/v0.18.0/changelog.html for the changes in this release.
Please see https://bidict.readthedocs.io/en/v0.18.0/changelog.html for the changes in this release.
Rename bidict.BidirectionalMapping.inv to ~bidict.BidirectionalMapping.inverse and make bidict.BidictBase.inv an alias for ~bidict.BidictBase.inverse. 86
bidict.BidirectionalMapping.__subclasshook__ now requires an inverse attribute rather than an inv attribute for a class to qualify as a virtual subclass. This breaking change is expected to affect few if any users.
Add Python 2/3-compatible bidict.compat.collections_abc alias.
Stop testing Python 3.4 on CI, and warn when Python 3 < 3.5 is detected rather than Python 3 < 3.3.
Python 3.4 reaches end of life on 2019-03-18. As of January 2019, 3.4 represents only about 3% of bidict downloads on PyPI Stats.
Rename bidict.BidirectionalMapping.inv to inverse and make bidict.BidictBase.inv an alias for inverse . #86
bidict.BidirectionalMapping.subclasshook now requires an inverse attribute rather than an inv attribute for a class to qualify as a virtual subclass. This breaking change is expected to affect few if any users.
Add Python 2/3-compatible bidict.compat.collections_abc alias.
Stop testing Python 3.4 on CI, and warn when Python 3 < 3.5 is detected rather than Python 3 < 3.3.
Python 3.4 reaches end of life on 2019-03-18. As of January 2019, 3.4 represents only about 3% of bidict downloads on PyPI Stats .
Please see https://bidict.readthedocs.io/en/v0.17.5/changelog.html for the changes in this release.
Please see https://bidict.readthedocs.io/en/v0.17.5/changelog.html for the changes in this release.
Improvements to performance and delegation logic, with minor breaking changes to semi-private APIs.
Remove the __delegate__ instance attribute added in the previous release. It was overly general and not worth the cost.
Instead of checking self.__delegate__ and delegating accordingly each time a possibly-delegating method is called, revert back to using "delegated-to-fwdm" mixin classes (now found in bidict._delegating_mixins), and resurrect a mutable bidict parent class that omits the mixins as bidict.MutableBidict.
Rename __repr_delegate__ to _repr_delegate.
Please see https://bidict.readthedocs.io/en/v0.17.4/changelog.html for the changes in this release.
Please see https://bidict.readthedocs.io/en/v0.17.4/changelog.html for the changes in this release.
Minor code, interop, and (semi-)private API improvements.
~bidict.OrderedBidict optimizations and code improvements.
Use bidicts for the backing _fwdm and _invm mappings, obviating the need to store key and value data in linked list nodes.
Refactor proxied- (i.e. delegated-) to-_fwdm logic for better composability and interoperability.
Drop the _Proxied* mixin classes and instead move their methods into ~bidict.BidictBase, which now checks for an object defined by the BidictBase.__delegate__ attribute. The BidictBase.__delegate__ object will be delegated to if the method is available on it, otherwise a default implementation (e.g. inherited from ~collections.abc.Mapping) will be used otherwise. Subclasses may set __delegate__ = None to opt out.
Consolidate _MutableBidict into bidict.bidict now that the dropped mixin classes make it unnecessary.
Change __repr_delegate__ to simply take a type like dict or list.
Upgrade to latest major sortedcontainers version (from v1 to v2) for the extending:\`SortedBidict`` Recipes`.
bidict.compat.{view,iter}{keys,values,items} on Python 2 no longer assumes the target object implements these methods, as they're not actually part of the ~collections.abc.Mapping interface, and provides fallback implementations when the methods are unavailable. This allows the extending:\`SortedBidict`` Recipes` to continue to work with sortedcontainers v2 on Python 2.
Please see https://bidict.readthedocs.io/en/v0.17.3/changelog.html for the changes in this release.
Please see https://bidict.readthedocs.io/en/v0.17.3/changelog.html for the changes in this release.
Improve packaging by adding a pyproject.toml and by including more supporting files in the distribution. #81
Drop pytest-runner and support for running tests via python setup.py test in preference to pytest or python -m pytest.
Please see https://bidict.readthedocs.io/en/v0.17.2/changelog.html for the changes in this release.
Please see https://bidict.readthedocs.io/en/v0.17.2/changelog.html for the changes in this release.
Memory usage improvements
Use less memory in the linked lists that back ~bidict.OrderedBidicts by storing node data unpacked rather than in (key, value) tuple objects.
Please see https://bidict.readthedocs.io/en/v0.17.1/changelog.html for the changes in this release.
Please see https://bidict.readthedocs.io/en/v0.17.1/changelog.html for the changes in this release.
Bugfix Release
Fix a regression in 0.17.0 that could cause erroneous behavior when updating items of an ~bidict.OrderedBidict's inverse, e.g. some_ordered_bidict.inv[foo] = bar.
Please see https://bidict.readthedocs.io/en/v0.17.0/changelog.html for the changes in this release.
Please see https://bidict.readthedocs.io/en/v0.17.0/changelog.html for the changes in this release.
Speedups and memory usage improvements
Pass ~bidict.BidictBase.keys, ~bidict.BidictBase.values, and ~bidict.BidictBase.items calls (as well as their iter* and view* counterparts on Python 2) through to the backing _fwdm and _invm dicts so that they run as fast as possible (i.e. at C speed on CPython), rather than using the slower implementations inherited from collections.abc.Mapping.
Use weakrefs in the linked lists that back ~bidict.OrderedBidicts to avoid creating strong reference cycles.
Memory for an ordered bidict that you create can now be reclaimed in CPython as soon as you no longer hold any references to it, rather than having to wait until the next garbage collection. #71
Misc
Add bidict.__version_info__ attribute to complement bidict.__version__.
Please see https://bidict.readthedocs.io/en/v0.16.0/changelog.html for the changes in this release.
Please see https://bidict.readthedocs.io/en/v0.16.0/changelog.html for the changes in this release.
Minor code and efficiency improvements to ~bidict.inverted and bidict._iter._iteritems_args_kw (formerly bidict.pairs()).
Minor Breaking API Changes
The following breaking changes are expected to affect few if any users.
Rename bidict.pairs() → bidict._iter._iteritems_args_kw.
Please see https://bidict.readthedocs.io/en/v0.15.0/changelog.html for the changes in this release.
Please see https://bidict.readthedocs.io/en/v0.15.0/changelog.html for the changes in this release.
Speedups and memory usage improvements
Use slots to speed up bidict attribute access and reduce memory usage. On Python 3, instantiating a large number of bidicts now uses ~57% the amount of memory that it used before, and on Python 2 only ~33% the amount of memory that it used before, in a simple but representative benchmark.
Use weakrefs to refer to a bidict's inverse internally, no longer creating a strong reference cycle. Memory for a bidict that you create can now be reclaimed in CPython as soon as you no longer hold any references to it, rather than having to wait for the next garbage collection. See the new addendum:\`bidict`` Avoids Reference Cycles` documentation. 24
Make bidict.BidictBase.__eq__ significantly more speed- and memory-efficient when comparing to a non-dict ~collections.abc.Mapping. (Mapping.__eq__()'s inefficient implementation will now never be used.) The implementation is now more reusable as well.
Make bidict.OrderedBidictBase.__iter__ as well as equality comparison slightly faster for ordered bidicts.
Minor Bugfixes
namedbidict now verifies that the provided keyname and valname are distinct, raising ValueError if they are equal.
namedbidict now raises TypeError if the provided base_type is not a ~bidict.BidirectionalMapping.
If you create a custom bidict subclass whose _fwdm_cls differs from its _invm_cls (as in the FwdKeySortedBidict example from the extending:\`SortedBidict`` Recipes`), the inverse bidirectional mapping type (with _fwdm_cls and _invm_cls swapped) is now correctly computed and used automatically for your custom bidict's ~bidict.BidictBase.inverse bidict.
Misc
Classes no longer have to provide an __inverted__ attribute to be considered virtual subclasses of ~bidict.BidirectionalMapping.
If bidict.inverted is passed an object with an __inverted__ attribute, it now ensures it is callable before returning the result of calling it.
~bidict.BidictBase.__repr__ no longer checks for a __reversed__ method to determine whether to use an ordered or unordered-style repr. It now calls the new __repr_delegate__ instead (which may be overridden if needed), for better composability.
Minor Breaking API Changes
The following breaking changes are expected to affect few if any users.
Split back out the ~bidict.BidictBase class from ~bidict.frozenbidict and ~bidict.OrderedBidictBase from FrozenOrderedBidict, reverting the merging of these in 0.14.0. Having e.g. issubclass(bidict, frozenbidict) == True was confusing, so this change restores issubclass(bidict, frozenbidict) == False.
See the updated other-bidict-types:Bidict Types Diagram and other-bidict-types:Polymorphism documentation.
Rename:
bidict.BidictBase.fwdm → ._fwdm
bidict.BidictBase.invm → ._invm
bidict.BidictBase.fwd_cls → ._fwdm_cls
bidict.BidictBase.inv_cls → ._invm_cls
bidict.BidictBase.isinv → ._isinv
Though overriding _fwdm_cls and _invm_cls remains supported (see extending), this is not a common enough use case to warrant public names. Most users do not need to know or care about any of these.
The ~bidict.RAISE, OVERWRITE, and IGNORE duplication policies are no longer available as attributes of DuplicationPolicy, and can now only be accessed as attributes of the bidict module namespace, which was the canonical way to refer to them anyway. It is now no longer possible to create an infinite chain like DuplicationPolicy.RAISE.RAISE.RAISE...
Make bidict.pairs() and bidict.inverted no longer importable from bidict.util, and now only importable from the top-level bidict module. (bidict.util was renamed bidict._util.)
Pickling ordered bidicts now requires at least version 2 of the pickle protocol. If you are using Python 3, pickle.DEFAULT_PROTOCOL is 3 anyway, so this will not affect you. However if you are using in Python 2, ~pickle.DEFAULT_PROTOCOL is 0, so you must now explicitly specify the version in your pickle.dumps calls, e.g. pickle.dumps(ob, 2).
Speedups and memory usage improvements
Use slots to speed up bidict attribute access and reduce memory usage. On Python 3, instantiating a large number of bidicts now uses ~57% the amount of memory that it used before, and on Python 2 only ~33% the amount of memory that it used before, in a simple but representative benchmark .
Use weakrefs to refer to a bidict’s inverse internally, no longer creating a strong reference cycle. Memory for a bidict that you create can now be reclaimed in CPython as soon as you no longer hold any references to it, rather than having to wait for the next garbage collection. See the new bidict Avoids Reference Cycles documentation. #24
Make bidict.BidictBase.eq() significantly more speed- and memory-efficient when comparing to a non- dict Mapping . ( Mapping.eq() 's inefficient implementation will now never be used.) The implementation is now more reusable as well.
Make bidict.OrderedBidictBase.iter() as well as equality comparison slightly faster for ordered bidicts.
Minor Bugfixes
namedbidict now verifies that the provided keyname and valname are distinct, raising ValueError if they are equal.
namedbidict now raises TypeError if the provided base_type is not a BidirectionalMapping .
If you create a custom bidict subclass whose _fwdm_cls differs from its _invm_cls (as in the FwdKeySortedBidict example from the SortedBidict Recipes ), the inverse bidirectional mapping type (with _fwdm_cls and _invm_cls swapped) is now correctly computed and used automatically for your custom bidict’s inverse bidict.
Misc
Classes no longer have to provide an inverted attribute to be considered virtual subclasses of BidirectionalMapping .
If bidict.inverted() is passed an object with an inverted attribute, it now ensures it is callable() before returning the result of calling it.
repr() no longer checks for a reversed method to determine whether to use an ordered or unordered-style repr. It now calls the new repr_delegate instead (which may be overridden if needed), for better composability.
Minor Breaking API Changes
The following breaking changes are expected to affect few if any users.
Split back out the BidictBase class from frozenbidict and OrderedBidictBase from FrozenOrderedBidict , reverting the merging of these in 0.14.0. Having e.g. issubclass(bidict, frozenbidict) == True was confusing, so this change restores issubclass(bidict, frozenbidict) == False .
See the updated Bidict Types Diagram and Polymorphism documentation.
Rename:
bidict.BidictBase.fwdm → ._fwdm
bidict.BidictBase.invm → ._invm
bidict.BidictBase.fwd_cls → ._fwdm_cls
bidict.BidictBase.inv_cls → ._invm_cls
bidict.BidictBase.isinv → ._isinv
Though overriding _fwdm_cls and _invm_cls remains supported (see Extending bidict ), this is not a common enough use case to warrant public names. Most users do not need to know or care about any of these.
The RAISE , OVERWRITE , and IGNORE duplication policies are no longer available as attributes of DuplicationPolicy , and can now only be accessed as attributes of the bidict module namespace, which was the canonical way to refer to them anyway. It is now no longer possible to create an infinite chain like DuplicationPolicy.RAISE.RAISE.RAISE...
Make bidict.pairs() and bidict.inverted() no longer importable from bidict.util , and now only importable from the top-level bidict module. ( bidict.util was renamed bidict._util .)
Pickling ordered bidicts now requires at least version 2 of the pickle protocol. If you are using Python 3, pickle.DEFAULT_PROTOCOL is 3 anyway, so this will not affect you. However if you are using in Python 2, DEFAULT_PROTOCOL is 0, so you must now explicitly specify the version in your pickle.dumps() calls, e.g. pickle.dumps(ob, 2) .
On this page
Changelog
0.24.2 (not yet released)
0.24.1 (2026-08-25)
0.24.0 (2026-08-24)
0.23.1 (2024-02-18)
0.23.0 (2024-02-14)
0.22.1 (2022-12-31)
0.22.0 (2022-03-23)
0.21.4 (2021-10-23)
0.21.3 (2021-09-05)
0.21.2 (2020-09-07)
0.21.1 (2020-09-07)
0.21.0 (2020-08-22)
0.20.0 (2020-07-23)
0.19.0 (2020-01-09)
0.18.4 (2020-11-02)
0.18.3 (2019-09-22)
0.18.2 (2019-09-08)
0.18.1 (2019-09-03)
0.18.0 (2019-02-14)
0.17.5 (2018-11-19)
0.17.4 (2018-11-14)
0.17.3 (2018-09-18)
0.17.2 (2018-04-30)
0.17.1 (2018-04-28)
0.17.0 (2018-04-25)
0.16.0 (2018-04-06)
0.15.0 (2018-03-29)
Please see https://bidict.readthedocs.io/changelog.html for the bidict changelog.
Please see https://bidict.readthedocs.io/changelog.html for the bidict changelog.
Nothing published for this version
Please see https://bidict.readthedocs.io/changelog.html for the bidict changelog.
Please see https://bidict.readthedocs.io/changelog.html for the bidict changelog.
Please see https://bidict.readthedocs.io/en/v0.14.2/changelog.html for the changes in this release.
Please see https://bidict.readthedocs.io/en/v0.14.2/changelog.html for the changes in this release.
Please see https://bidict.readthedocs.io/en/v0.14.1/changelog.html for the changes in this release.
Please see https://bidict.readthedocs.io/en/v0.14.1/changelog.html for the changes in this release.
Please see https://bidict.readthedocs.io/en/v0.14.0/changelog.html for the changes in this release.
Please see https://bidict.readthedocs.io/en/v0.14.0/changelog.html for the changes in this release.
Please see https://bidict.readthedocs.io/en/v0.13.1/changelog.html for the changes in this release.
Please see https://bidict.readthedocs.io/en/v0.13.1/changelog.html for the changes in this release.
Please see https://bidict.readthedocs.io/en/v0.13.0/changelog.html for the changes in this release.
Please see https://bidict.readthedocs.io/en/v0.13.0/changelog.html for the changes in this release.
Please see https://bidict.readthedocs.io/en/v0.12.0/changelog.html for the changes in this release.
Please see https://bidict.readthedocs.io/en/v0.12.0/changelog.html for the changes in this release.
Please see https://bidict.readthedocs.io/en/v0.11.0/changelog.html for the changes in this release.
Please see https://bidict.readthedocs.io/en/v0.11.0/changelog.html for the changes in this release.
Please see http://bidict.readthedocs.io/en/v0.10.0.post1/changelog.html for the changes in this release.
Please see http://bidict.readthedocs.io/en/v0.10.0.post1/changelog.html for the changes in this release.
Please see http://bidict.readthedocs.io/en/v0.10.0.post1/changelog.html for the changes in this release.
Please see http://bidict.readthedocs.io/en/v0.10.0.post1/changelog.html for the changes in this release.
Please see https://bidict.readthedocs.io/en/v0.9.0.post1/changelog.html for the changes in this release.
Please see https://bidict.readthedocs.io/en/v0.9.0.post1/changelog.html for the changes in this release.
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Your coding agent can read these notes before it upgrades. Set up the MCP server →