.. Forward declarations for all the custom interpreted text roles that
   Sphinx defines and that are used below. This helps Sphinx-unaware tools
   (e.g. rst2html, PyPI's and GitHub's renderers, etc.).
.. role:: doc
.. role:: ref


Changelog
=========

.. image:: https://img.shields.io/badge/GitHub-sponsor-ff69b4
  :target: https://github.com/sponsors/jab
  :alt: Sponsor


:sup:`If you or your organization depends on bidict,
please consider sponsoring bidict on GitHub.`


.. tip::
   Watch `bidict releases on GitHub <https://github.com/jab/bidict/releases>`__
   to be notified when new versions of bidict are published.
   Click the "Watch" dropdown, choose "Custom", and then choose "Releases".


0.23.1 (2024-02-18)
-------------------

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.
:issue:`310`


0.23.0 (2024-02-14)
-------------------

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.
  :class:`~bidict.frozenbidict` now provides everything
  that ``FrozenOrderedBidict`` provided
  (including :class:`reversibility <collections.abc.Reversible>`)
  on all supported Python versions,
  but with less space overhead.

- Remove ``namedbidict`` due to low usage.

- Remove the ``kv`` field of :class:`~bidict.OnDup`
  which specified the :class:`~bidict.OnDupAction` to take
  in the case of :ref:`basic-usage:key and value duplication`.
  The :attr:`~bidict.OnDup.val` field now specifies the action to take
  in the case of
  :ref:`basic-usage:key and value duplication`
  as well as
  :ref:`just value duplication <basic-usage:values must be unique>`.

- Improve type hints for the
  :attr:`~bidict.BidictBase.inv` shortcut alias
  for :attr:`~bidict.BidictBase.inverse`.

- Fix a bug where calls like
  ``bidict(None)``, ``bi.update(False)``, etc.
  would fail to raise a :class:`TypeError`.

- All :meth:`~bidict.BidictBase.__init__`,
  :meth:`~bidict.MutableBidict.update`,
  and related methods
  now handle `SupportsKeysAndGetItem
  <https://github.com/python/typeshed/blob/3eb9ff/stdlib/_typeshed/__init__.pyi#L128-L131>`__
  objects that are not :class:`~collections.abc.Mapping`\s
  the same way that `MutableMapping.update()
  <https://github.com/python/cpython/blob/v3.11.5/Lib/_collections_abc.py#L943>`__ does,
  before falling back to handling the provided object as an iterable of pairs.

- The :func:`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 :class:`collections.OrderedDict`\'s :func:`repr`
  `in Python 3.12 <https://github.com/python/cpython/pull/101661>`__.

- 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 <https://github.com/pypa/trove-classifiers>`__
  that declare support for specific Python versions in package metadata.


0.22.1 (2022-12-31)
-------------------

- 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 :func:`bidict.inverted`
  to return an :class:`~collections.abc.Iterator`,
  rather than an :class:`~collections.abc.Iterable`.


0.22.0 (2022-03-23)
-------------------

- 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 :mod:`bidict`.

- Update the implementations and type annotations of
  :meth:`bidict.BidictBase.keys` and
  :meth:`bidict.BidictBase.values` to make use of the new
  :class:`~bidict.BidictKeysView` type,
  which works a bit better with type checkers.

- Inverse bidict instances are now computed lazily the first time
  the :attr:`~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 :meth:`~bidict.BidictBase.copy`.
  In a microbenchmark on Python 3.10,
  this now performs **10-20x faster**.

- Optimize rolling back
  :ref:`failed updates to a bidict <basic-usage:Updates Fail Clean>`
  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 :meth:`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 :meth:`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 :meth:`~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
  :class:`~collections.abc.MappingView` objects returned by
  :meth:`bidict.OrderedBidict.keys`,
  :meth:`bidict.OrderedBidict.values <bidict.BidictBase.values>`, and
  :meth:`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
  :meth:`bidict.BidictBase.__eq__` was always returning False
  rather than :obj:`NotImplemented`
  in the case that the argument was not a
  :class:`~collections.abc.Mapping`,
  defeating the argument's own ``__eq__()`` if implemented.
  As a notable example, bidicts now correctly compare equal to
  :obj:`unittest.mock.ANY`.

- :class:`bidict.BidictBase` now adds a ``__reversed__`` implementation
  to subclasses that don't have an overridden implementation
  depending on whether both their backing mappings are
  :class:`~collections.abc.Reversible`.
  Previously, a ``__reversed__`` implementation was only added to
  :class:`~bidict.BidictBase` when ``BidictBase._fwdm_cls`` was
  :class:`~collections.abc.Reversible`.
  So if a :class:`~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 :class:`~bidict.BidictBase`.
  This is no longer necessary thanks to bidict's new
  :meth:`object.__init_subclass__` logic.

- The
  :class:`~collections.abc.MappingView` objects
  returned by
  :meth:`bidict.OrderedBidict.keys`,
  :meth:`bidict.OrderedBidict.values <bidict.BidictBase.values>`, and
  :meth:`bidict.OrderedBidict.items`
  are now
  :class:`~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 <https://www.python.org/dev/peps/pep-0584/>`__).

  See `the tests <https://github.com/jab/bidict/blob/main/tests/>`__
  for examples.

- Update docstrings for
  :meth:`bidict.BidictBase.keys`,
  :meth:`bidict.BidictBase.values`, and
  :meth:`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 :class:`~bidict.BidictBase`,
  but no longer requires *base_type* to provide
  an ``_isinv`` attribute,
  which :class:`~bidict.BidictBase` subclasses no longer provide.

- When attempting to pickle a bidict's inverse whose class was
  :ref:`dynamically generated
  <extending:Dynamic Inverse Class Generation>`,
  and no reference to the dynamically-generated class has been stored
  anywhere in :data:`sys.modules` where :mod:`pickle` can find it,
  the pickle call is now more likely to succeed
  rather than failing with a :class:`~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.


0.21.4 (2021-10-23)
-------------------

Explicitly declare support for Python 3.10
as well as some minor internal improvements.


0.21.3 (2021-09-05)
-------------------

- All bidicts now provide the :meth:`~bidict.BidictBase.equals_order_sensitive` method,
  not just :class:`~bidict.OrderedBidict`\s.

  Since support for Python < 3.6 was dropped in v0.21.0,
  :class:`dict`\s provide a deterministic ordering
  on all supported Python versions,
  and as a result, all bidicts do too.
  So now even non-:class:`Ordered <bidict.OrderedBidict>` bidicts
  might as well provide :meth:`~bidict.BidictBase.equals_order_sensitive`.

  See the updated
  :ref:`other-bidict-types:What about order-preserving dicts?` docs for more info.

- Take better advantage of the fact that dicts became
  :class:`reversible <collections.abc.Reversible>` in Python 3.8.

  Specifically, now even non-:class:`Ordered <bidict.OrderedBidict>` bidicts
  provide a :meth:`~bidict.BidictBase.__reversed__` implementation on Python 3.8+
  that calls :func:`reversed` on the backing ``_fwdm`` mapping.

  As a result, if you are using Python 3.8+,
  :class:`~bidict.frozenbidict` now gives you everything that
  ``FrozenOrderedBidict`` gives you,
  but with less space overhead.

- Drop `setuptools_scm <https://github.com/pypa/setuptools_scm>`__
  as a ``setup_requires`` dependency.

- Remove the ``bidict.__version_info__`` attribute.


0.21.2 (2020-09-07)
-------------------

- Include `py.typed <https://www.python.org/dev/peps/pep-0561/#packaging-type-information>`__
  file to mark :mod:`bidict` as type hinted.


0.21.1 (2020-09-07)
-------------------

This release was yanked and replaced with the 0.21.2 release,
which actually provides the intended changes.


0.21.0 (2020-08-22)
-------------------

- :mod:`bidict` now provides
  `type hints <https://www.python.org/dev/peps/pep-0484/>`__! ⌨️ ✅

  Adding type hints to :mod:`bidict` poses particularly interesting challenges
  due to the combination of generic types,
  dynamically-generated types
  (such as :ref:`inverse bidict classes <extending:Dynamic Inverse Class Generation>`
  and ``namedbidict``\s),
  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 <https://github.com/python/typing/issues/548#issuecomment-621195693>`__),
  too-narrow type hints for :class:`collections.abc.Mapping`
  (`python/typeshed#4435 <https://github.com/python/typeshed/issues/4435>`__),
  a :class:`typing.Generic` bug in Python 3.6
  (`BPO-41451 <https://bugs.python.org/issue41451>`__), etc.

  That said, this release should provide a solid foundation
  for code using :mod:`bidict` that enables static type checking.

  As always, if you spot any opportunities to improve :mod:`bidict`
  (including its new type hints),
  please don't hesitate to submit a PR!

- Add :class:`bidict.MutableBidirectionalMapping` ABC.

  The :ref:`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 <https://pypistats.org/packages/bidict>`__,
  and lacks support for
  `variable type hint syntax <https://www.python.org/dev/peps/pep-0526/>`__,
  `ordered dicts <https://stackoverflow.com/a/39980744>`__,
  and :attr:`object.__init_subclass__`.

- Remove the no-longer-needed ``bidict.compat`` module.

- Move :ref:`inverse bidict class access <extending:Dynamic Inverse Class Generation>`
  from a property to an attribute set in
  :attr:`~bidict.BidictBase.__init_subclass__`,
  to save function call overhead on repeated access.

- :meth:`bidict.OrderedBidictBase.__iter__` no longer accepts
  a ``reverse`` keyword argument so that it matches the signature of
  :meth:`container.__iter__`.

- Set the ``__module__`` attribute of various :mod:`bidict` types
  (using :func:`sys._getframe` when necessary)
  so that private, internal modules are not exposed
  e.g. in classes' repr strings.

- ``namedbidict`` now immediately raises :class:`TypeError`
  if the provided ``base_type`` does not provide
  ``_isinv`` or :meth:`~object.__getstate__`,
  rather than succeeding with a class whose instances may raise
  :class:`AttributeError` when these attributes are accessed.


0.20.0 (2020-07-23)
-------------------

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
  :meth:`~bidict.MutableBidict.put` and :meth:`~bidict.MutableBidict.putall`.

- The ``on_dup_key``, ``on_dup_val``, and ``on_dup_kv``
  :class:`~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 :class:`collections.abc.Mapping`.
  :issue:`111`


0.19.0 (2020-01-09)
-------------------

- Drop support for Python 2
  :ref:`as promised in v0.18.2 <changelog:0.18.2 (2019-09-08)>`.

  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 :class:`UserWarning` will now be emitted if these are used.

  :attr:`bidict.DROP_OLD` and :attr:`bidict.DROP_NEW` should be used instead.

- Rename ``DuplicationPolicy`` to :class:`~bidict.OnDupAction`
  (and implement it via an :class:`~enum.Enum`).

  An :class:`~bidict.OnDupAction` may be one of
  :attr:`~bidict.RAISE`,
  :attr:`~bidict.DROP_OLD`, or
  :attr:`~bidict.DROP_NEW`.

- Expose the new :class:`~bidict.OnDup` class
  to contain the three :class:`~bidict.OnDupAction`\s
  that should be taken upon encountering
  the three kinds of duplication that can occur
  (*key*, *val*, *kv*).

- Provide the
  :attr:`~bidict.ON_DUP_DEFAULT`,
  :attr:`~bidict.ON_DUP_RAISE`, and
  :attr:`~bidict.ON_DUP_DROP_OLD`
  :class:`~bidict.OnDup` convenience instances.

- Deprecate the
  ``on_dup_key``, ``on_dup_val``, and ``on_dup_kv`` arguments
  of :meth:`~bidict.MutableBidict.put` and :meth:`~bidict.MutableBidict.putall`.
  A :class:`UserWarning` will now be emitted if these are used.

  These have been subsumed by the new *on_dup* argument,
  which takes an :class:`~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 :attr:`~bidict.ON_DUP_DROP_OLD`.
  Or just don't pass an *on_dup* argument
  to use the default value of :attr:`~bidict.ON_DUP_RAISE`.

  The :ref:`basic-usage:Values Must Be Unique` docs
  have been updated accordingly.

- Deprecate the
  ``on_dup_key``, ``on_dup_val``, and ``on_dup_kv``
  :class:`~bidict.bidict` class attributes.
  A :class:`UserWarning` will now be emitted if these are used.

  These have been subsumed by the new
  :attr:`~bidict.BidictBase.on_dup` class attribute,
  which takes an :class:`~bidict.OnDup` instance.

  See the updated :doc:`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 :class:`dict`\s
  in the bidict types for which this is possible.

- Move
  :meth:`bidict.BidictBase.values` to
  ``bidict.BidirectionalMapping.values``,
  since the implementation is generic.

- No longer use ``__all__`` in :mod:`bidict`'s ``__init__.py``.


0.18.4 (2020-11-02)
-------------------

- Backport fix from v0.20.0
  that removes ``bidict.BidirectionalMapping.__subclasshook__``
  due to lack of use and maintenance cost.


0.18.3 (2019-09-22)
-------------------

- Improve validation of names passed to ``namedbidict``:
  Use :meth:`str.isidentifier` on Python 3,
  and a better regex on Python 2.

- On Python 3,
  set :attr:`~definition.__qualname__` on ``namedbidict`` classes
  based on the provided ``typename`` argument.


0.18.2 (2019-09-08)
-------------------

- Warn that Python 2 support will be dropped in a future release
  when Python 2 is detected.


0.18.1 (2019-09-03)
-------------------

- Fix a regression introduced by the memory optimizations added in 0.15.0
  which caused
  :func:`deepcopied <copy.deepcopy>` and
  :func:`unpickled <pickle.loads>`
  bidicts to have their inverses set incorrectly.
  :issue:`94`


0.18.0 (2019-02-14)
-------------------

- Rename ``bidict.BidirectionalMapping.inv`` to :attr:`~bidict.BidirectionalMapping.inverse`
  and make :attr:`bidict.BidictBase.inv` an alias for :attr:`~bidict.BidictBase.inverse`.
  :issue:`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 <https://www.python.org/dev/peps/pep-0429/>`__ on 2019-03-18.
  As of January 2019, 3.4 represents only about 3% of bidict downloads on
  `PyPI Stats <https://pypistats.org/packages/bidict>`__.


0.17.5 (2018-11-19)
-------------------

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 :class:`bidict.MutableBidict`.

- Rename ``__repr_delegate__`` to ``_repr_delegate``.


0.17.4 (2018-11-14)
-------------------

Minor code, interop, and (semi-)private API improvements.

- :class:`~bidict.OrderedBidict` optimizations and code improvements.

  Use ``bidict``\s 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 :class:`~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 :class:`~collections.abc.Mapping`)
  will be used otherwise.
  Subclasses may set ``__delegate__ = None`` to opt out.

  Consolidate ``_MutableBidict`` into :class:`bidict.bidict`
  now that the dropped mixin classes make it unnecessary.

- Change ``__repr_delegate__``
  to simply take a type like :class:`dict` or :class:`list`.

- Upgrade to latest major
  `sortedcontainers <https://github.com/grantjenks/python-sortedcontainers>`__
  version (from v1 to v2)
  for the :ref:`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
  :class:`~collections.abc.Mapping` interface,
  and provides fallback implementations when the methods are unavailable.
  This allows the :ref:`extending:\`\`SortedBidict\`\` Recipes`
  to continue to work with sortedcontainers v2 on Python 2.


0.17.3 (2018-09-18)
-------------------

- Improve packaging by adding a pyproject.toml
  and by including more supporting files in the distribution.
  `#81 <https://github.com/jab/bidict/pull/81>`__

- Drop pytest-runner and support for running tests via ``python setup.py test``
  in preference to ``pytest`` or ``python -m pytest``.


0.17.2 (2018-04-30)
-------------------

**Memory usage improvements**

- Use less memory in the linked lists that back
  :class:`~bidict.OrderedBidict`\s
  by storing node data unpacked
  rather than in (key, value) tuple objects.


0.17.1 (2018-04-28)
-------------------

**Bugfix Release**

Fix a regression in 0.17.0 that could cause erroneous behavior
when updating items of an :class:`~bidict.OrderedBidict`'s inverse,
e.g. ``some_ordered_bidict.inv[foo] = bar``.


0.17.0 (2018-04-25)
-------------------

**Speedups and memory usage improvements**

- Pass
  :meth:`~bidict.BidictBase.keys`,
  :meth:`~bidict.BidictBase.values`, and
  :meth:`~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 :class:`collections.abc.Mapping`.

- Use weakrefs in the linked lists that back
  :class:`~bidict.OrderedBidict`\s
  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 <https://github.com/jab/bidict/pull/71>`__


**Misc**

- Add ``bidict.__version_info__`` attribute
  to complement :attr:`bidict.__version__`.


0.16.0 (2018-04-06)
-------------------

Minor code and efficiency improvements to
:func:`~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``.


0.15.0 (2018-03-29)
-------------------

**Speedups and memory usage improvements**

- Use :ref:`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 <https://github.com/jab/bidict/pull/56#issuecomment-368203591>`__.

- 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
  :ref:`addendum:\`\`bidict\`\` Avoids Reference Cycles`
  documentation.
  :issue:`24`

- Make :func:`bidict.BidictBase.__eq__` significantly
  more speed- and memory-efficient when comparing to
  a non-:class:`dict` :class:`~collections.abc.Mapping`.
  (``Mapping.__eq__()``\'s inefficient implementation will now never be used.)
  The implementation is now more reusable as well.

- Make :func:`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 :class:`ValueError` if they are equal.

- ``namedbidict`` now raises :class:`TypeError`
  if the provided ``base_type``
  is not a :class:`~bidict.BidirectionalMapping`.

- If you create a custom bidict subclass whose ``_fwdm_cls``
  differs from its ``_invm_cls``
  (as in the ``FwdKeySortedBidict`` example
  from the :ref:`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
  :attr:`~bidict.BidictBase.inverse` bidict.

**Misc**

- Classes no longer have to provide an ``__inverted__``
  attribute to be considered virtual subclasses of
  :class:`~bidict.BidirectionalMapping`.

- If :func:`bidict.inverted` is passed
  an object with an ``__inverted__`` attribute,
  it now ensures it is :func:`callable`
  before returning the result of calling it.

- :func:`~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 :class:`~bidict.BidictBase` class
  from :class:`~bidict.frozenbidict`
  and :class:`~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 :ref:`other-bidict-types:Bidict Types Diagram`
  and :ref:`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 :doc:`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 :attr:`~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 :mod:`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 :func:`bidict.inverted`
  no longer importable from ``bidict.util``,
  and now only importable from the top-level :mod:`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,
  :obj:`pickle.DEFAULT_PROTOCOL` is 3 anyway,
  so this will not affect you.
  However if you are using in Python 2,
  :obj:`~pickle.DEFAULT_PROTOCOL` is 0,
  so you must now explicitly specify the version
  in your :func:`pickle.dumps` calls,
  e.g. ``pickle.dumps(ob, 2)``.
