Bidict

Latest version: v0.23.1

Safety actively analyzes 620778 Python packages for vulnerabilities to keep your Python projects secure.

Scan your dependencies

Page 1 of 4

0.23.1

-------------------

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

-------------------

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

-------------------

- 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

-------------------

- 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

-------------------

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

0.21.3

-------------------

- 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.

Page 1 of 4

© 2024 Safety CLI Cybersecurity Inc. All Rights Reserved.