Skip to content

Commit

Permalink
Various API changes and other improvements.
Browse files Browse the repository at this point in the history
* 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`).

  A :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,
  a named (*key*, *val*, *kv*) tuple of :class:`~bidict.OnDupAction`\s
  that should be taken upon encountering
  the 3 kinds of duplication that can occur.

* 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.bidict.put` and :meth:`~bidict.bidict.putall`.
  A :class:`UserWarning` will now be emitted if these are used.

  They 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=DROP_NEW))``.
  Or better yet, pass one of the
  ``ON_DUP_*`` convenience instances
  instead if possible.

  See the updated :ref:`basic-usage:Values Must Be Unique` docs for more info.

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

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

  See the updated :doc:`extending` docs for example usage.

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

* No longer use ``__all__`` in ``bidict/__init__.py``.

* Cap max_size rather than disabling health checks and deadline as a
  less heavyhanded way to improve hypothesis test reliability on Travis.
  • Loading branch information
jab committed Jan 7, 2020
1 parent 20d643f commit 0ec3b8b
Show file tree
Hide file tree
Showing 27 changed files with 520 additions and 387 deletions.
30 changes: 15 additions & 15 deletions .travis.yml
Expand Up @@ -17,16 +17,10 @@ dist: 'xenial'
env:
global:
- 'INSTALL_EXTRAS=test'
# Some Travis builds began failing nondeterministically on 2019-12-19
# (starting with https://travis-ci.org/jab/bidict/builds/627347551)
# due to no output being received for TIMEOUT minutes (10, by default).
# Increasing the timeout by wrapping with 'travis_wait 50' did not help,
# nor did disabling pytest output capturing.
# Reducing HYPOTHESIS_MAX_EXAMPLES seems to reduce the frequency of the issue,
# but it still continues to occur.
# Try reducing HYPOTHESIS_MAX_EXAMPLES here as well as
# wrapping run_tests.py with 'travis_retry' below.
- 'HYPOTHESIS_MAX_EXAMPLES=100'
# Tweak Hypothesis params so tests pass reliably since Travis workers are slow.
- 'HYPOTHESIS_MAX_EXAMPLES=100' # See tests/conftest.py
- 'HYPOTHESIS_DEADLINE=300'
- 'HYPOTHESIS_GEN_MAX_SIZE=16' # See tests/properties/_strategies.py


before_install: # Ensure we have the required versions of Python and Pip.
Expand Down Expand Up @@ -71,13 +65,19 @@ script: # Run the test suite.
- |
if [[ "$TRAVIS_EVENT_TYPE" == "cron" ]]; then
export PYTEST_ADDOPTS="${PYTEST_ADDOPTS} --hypothesis-show-statistics"
# Commenting this out due to recent Travis flakiness (see comments above):
# export HYPOTHESIS_MAX_EXAMPLES="2000" See tests/conftest.py
export HYPOTHESIS_MAX_EXAMPLES="150"
export HYPOTHESIS_GEN_MAX_SIZE="32"
export HYPOTHESIS_DEADLINE="500"
fi
# Without this, pypy3 with coverage on Travis is too slow to pass reliably.
if [[ "$TASK" == "test-linux-pypy3" ]]; then
export HYPOTHESIS_MAX_EXAMPLES="100"
export HYPOTHESIS_GEN_MAX_SIZE="8"
fi
if [[ "$COVERAGE" ]]; then
export PYTEST_ADDOPTS="${PYTEST_ADDOPTS} --cov=bidict --cov-config=.coveragerc"
fi
travis_retry python3 ./run_tests.py
python3 ./run_tests.py
after_script:
Expand Down Expand Up @@ -142,7 +142,7 @@ matrix:

- env: 'TASK=docs-linkcheck INSTALL_EXTRAS=docs'
before_install: 'skip'
script: '(cd docs && travis_retry make linkcheck)'
script: '(cd docs && make linkcheck)'

## Remaining CPython versions on Linux.
- python: '3.7'
Expand All @@ -161,7 +161,7 @@ matrix:
os: 'osx'
language: 'generic'

## TODO: Try Travis's new Windows support once it supports Python.
## Try Travis's new Windows support once it supports Python?
### - env: 'TASK=test-windows-cpython-3.x'
### os: 'windows'

Expand Down
88 changes: 70 additions & 18 deletions CHANGELOG.rst
Expand Up @@ -37,20 +37,74 @@ and choose "Releases".
This makes bidict more efficient on Python 3
and enables further improvement to bidict in the future.

* Move
:meth:`bidict.BidictBase.values` to
:meth:`bidict.BidirectionalMapping.values`,
since the implementation is generic.
* 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,
a three-element :func:`namedtuple <collections.namedtuple>`
of :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.bidict.put` and :meth:`~bidict.bidict.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))``.
Or better yet, pass one of the instances already provided
(such as :attr:`~bidict.ON_DUP_RAISE`)
instead if possible.

See the updated :ref:`basic-usage:Values Must Be Unique` docs for more info.

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

These have been subsumed by the new
:attr:`~bidict.bidict.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
:meth:`~bidict.BidirectionalMapping.keys`,
:meth:`~bidict.BidirectionalMapping.values`, and
:meth:`~bidict.BidirectionalMapping.items`,
and now also provide a more efficient implementation of
:meth:`~bidict.BidirectionalMapping.__iter__`
by delegating to backing dicts
by delegating to backing :class:`dict`\s
in the bidict types for which this is possible.

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

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


0.18.3 (2019-09-22)
-------------------
Expand Down Expand Up @@ -356,10 +410,9 @@ The following breaking changes are expected to affect few if any users.
Most users do not need to know or care about any of these.

- The :attr:`~bidict.RAISE`,
:attr:`~bidict.OVERWRITE`, and
:attr:`~bidict.IGNORE`
``OVERWRITE``, and ``IGNORE``
duplication policies are no longer available as attributes of
:class:`bidict.DuplicationPolicy`,
``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.
Expand Down Expand Up @@ -530,21 +583,20 @@ This release includes multiple API simplifications and improvements.

- ``loosebidict`` and ``looseorderedbidict`` have been removed.
A simple recipe to implement equivalents yourself is now given in
:ref:`extending:OverwritingBidict Recipe`.
:doc:`extending`.

- Rename ``FrozenBidictBase._compute_hash()`` →
``frozenbidict.compute_hash()``.

- Rename ``DuplicationBehavior`` →
:class:`~bidict.DuplicationPolicy`.
- Rename ``DuplicationBehavior`` → ``DuplicationPolicy``.

- Rename:

- ``bidict.BidictBase._fwd_class`` → ``.fwd_cls``
- ``bidict.BidictBase._inv_class`` → ``.inv_cls``
- ``bidict.BidictBase._on_dup_key`` → :attr:`~bidict.BidictBase.on_dup_key`
- ``bidict.BidictBase._on_dup_val`` → :attr:`~bidict.BidictBase.on_dup_val`
- ``bidict.BidictBase._on_dup_kv`` → :attr:`~bidict.BidictBase.on_dup_kv`
- ``BidictBase._fwd_class`` → ``.fwd_cls``
- ``BidictBase._inv_class`` → ``.inv_cls``
- ``BidictBase._on_dup_key`` → ``on_dup_key``
- ``BidictBase._on_dup_val`` → ``on_dup_val``
- ``BidictBase._on_dup_kv`` → ``on_dup_kv``


0.13.1 (2017-03-15)
Expand Down Expand Up @@ -648,8 +700,8 @@ This release includes multiple API simplifications and improvements.
These can take the following values:

- :attr:`~bidict.RAISE`
- :attr:`~bidict.OVERWRITE`
- :attr:`~bidict.IGNORE`
- ``OVERWRITE``
- ``IGNORE``

``on_dup_kv`` can also take ``ON_DUP_VAL``.

Expand Down
28 changes: 12 additions & 16 deletions README.rst
Expand Up @@ -33,23 +33,19 @@ Status
:target: https://codecov.io/gh/jab/bidict
:alt: Test coverage

.. image:: https://img.shields.io/lgtm/alerts/github/jab/bidict.svg
:target: https://lgtm.com/projects/g/jab/bidict/
:alt: LGTM alerts

.. image:: https://api.codacy.com/project/badge/Grade/6628756a73254cd895656348236833b8
:target: https://www.codacy.com/app/jab/bidict
:alt: Codacy grade

.. image:: https://bestpractices.coreinfrastructure.org/projects/2354/badge
:target: https://bestpractices.coreinfrastructure.org/en/projects/2354
:alt: CII best practices badge

.. image:: https://img.shields.io/badge/tidelift-pro%20support-orange.svg
:target: https://tidelift.com/subscription/pkg/pypi-bidict?utm_source=pypi-bidict&utm_medium=referral&utm_campaign=docs
:alt: Paid support available via Tidelift

.. Hide to reduce clutter
.. image:: https://img.shields.io/lgtm/alerts/github/jab/bidict.svg
:target: https://lgtm.com/projects/g/jab/bidict/
:alt: LGTM alerts
.. image:: https://api.codacy.com/project/badge/Grade/6628756a73254cd895656348236833b8
:target: https://www.codacy.com/app/jab/bidict
:alt: Codacy grade
.. image:: https://bestpractices.coreinfrastructure.org/projects/2354/badge
:target: https://bestpractices.coreinfrastructure.org/en/projects/2354
:alt: CII best practices badge
.. image:: https://img.shields.io/badge/tidelift-pro%20support-orange.svg
:target: https://tidelift.com/subscription/pkg/pypi-bidict?utm_source=pypi-bidict&utm_medium=referral&utm_campaign=docs
:alt: Paid support available via Tidelift
.. image:: https://ci.appveyor.com/api/projects/status/gk133415udncwto3/branch/master?svg=true
:target: https://ci.appveyor.com/project/jab/bidict
:alt: AppVeyor (Windows) build status
Expand Down
99 changes: 51 additions & 48 deletions bidict/__init__.py
Expand Up @@ -26,8 +26,9 @@
#==============================================================================


"""
The bidirectional mapping library for Python.
"""The bidirectional mapping library for Python.
bidict by example:
.. code-block:: python
Expand All @@ -48,73 +49,75 @@
.. :license: MPLv2. See LICENSE for details.
"""

from warnings import warn
from .compat import PY2, PYMAJOR, PYMINOR
# Use private aliases to not re-export these publicly (for Sphinx automodule with imported-members).
from functools import partial as _partial
from types import ModuleType as _ModuleType
from sys import modules as _modules
from warnings import warn as _warn

from . import compat as _c

if PY2:

if _c.PY2:
raise ImportError('Python 3 is required.')

if (PYMAJOR, PYMINOR) < (3, 5): # pragma: no cover
warn('This version of bidict is untested on Python < 3.5 and may not work.')
_warn = _partial(_warn, stacklevel=2) # pylint: disable=invalid-name

if (_c.PYMAJOR, _c.PYMINOR) < (3, 5): # pragma: no cover
_warn('This version of bidict is untested on Python < 3.5 and may not work.')

# The rest of this file only collects functionality implemented in the rest of the
# source and exports it under the `bidict` module namespace (via `__all__`).
# source for the purposes of exporting it under the `bidict` module namespace.
# pylint: disable=wrong-import-position
# flake8: noqa: F401 (imported but unused)
from ._abc import BidirectionalMapping
from ._base import BidictBase
from ._mut import MutableBidict
from ._bidict import bidict
from ._dup import DuplicationPolicy, IGNORE, OVERWRITE, RAISE
from ._exc import (
BidictException, DuplicationError,
KeyDuplicationError, ValueDuplicationError, KeyAndValueDuplicationError)
from ._util import inverted
from ._frozenbidict import frozenbidict
from ._frozenordered import FrozenOrderedBidict
from ._named import namedbidict
from ._orderedbase import OrderedBidictBase
from ._orderedbidict import OrderedBidict
from ._dup import (
ON_DUP_DEFAULT, ON_DUP_RAISE, ON_DUP_DROP_OLD,
RAISE, DROP_OLD, DROP_NEW, OnDup, OnDupAction,
)
from ._exc import (
BidictException,
DuplicationError, KeyDuplicationError, ValueDuplicationError, KeyAndValueDuplicationError,
)
from ._util import inverted
from .metadata import (
__author__, __maintainer__, __copyright__, __email__, __credits__, __url__,
__license__, __status__, __description__, __keywords__, __version__, __version_info__)


__all__ = (
'__author__',
'__maintainer__',
'__copyright__',
'__email__',
'__credits__',
'__license__',
'__status__',
'__description__',
'__keywords__',
'__url__',
'__version__',
'__version_info__',
'BidirectionalMapping',
'BidictException',
'DuplicationPolicy',
'IGNORE',
'OVERWRITE',
'RAISE',
'DuplicationError',
'KeyDuplicationError',
'ValueDuplicationError',
'KeyAndValueDuplicationError',
'BidictBase',
'MutableBidict',
'frozenbidict',
'bidict',
'namedbidict',
'FrozenOrderedBidict',
'OrderedBidictBase',
'OrderedBidict',
'inverted',
__license__, __status__, __description__, __keywords__, __version__, __version_info__,
)


# Aliases for deprecated constants. TODO: remove in a future release.
OVERWRITE = DROP_OLD
IGNORE = DROP_NEW


class _BidictModuleType(_ModuleType): # pylint: disable=too-few-public-methods
"""Compatibility shim."""

def __getattribute__(self, name):
if name == 'OVERWRITE':
_warn('bidict.OVERWRITE has been deprecated, use bidict.DROP_OLD instead.')
return DROP_OLD
if name == 'IGNORE':
_warn('bidict.IGNORE has been deprecated, use bidict.DROP_NEW instead.')
return DROP_NEW
return object.__getattribute__(self, name)


try:
_modules[__name__].__class__ = _BidictModuleType
except TypeError:
pass


# * Code review nav *
#==============================================================================
# Current: __init__.py Next: _abc.py →
Expand Down

0 comments on commit 0ec3b8b

Please sign in to comment.