Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Various API and other improvements. #107

Merged
merged 1 commit into from
Jan 7, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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 (
jab marked this conversation as resolved.
Show resolved Hide resolved
ON_DUP_DEFAULT, ON_DUP_RAISE, ON_DUP_DROP_OLD,
RAISE, DROP_OLD, DROP_NEW, OnDup, OnDupAction,
)
from ._exc import (
jab marked this conversation as resolved.
Show resolved Hide resolved
BidictException,
DuplicationError, KeyDuplicationError, ValueDuplicationError, KeyAndValueDuplicationError,
)
from ._util import inverted
jab marked this conversation as resolved.
Show resolved Hide resolved
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