123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384 |
- # -*- coding: utf-8 -*-
- # Copyright 2018 Joshua Bronson. All Rights Reserved.
- #
- # This Source Code Form is subject to the terms of the Mozilla Public
- # License, v. 2.0. If a copy of the MPL was not distributed with this
- # file, You can obtain one at http://mozilla.org/MPL/2.0/.
- #==============================================================================
- # * Welcome to the bidict source code *
- #==============================================================================
- # Doing a code review? You'll find a "Code review nav" comment like the one
- # below at the top and bottom of the most important source files. This provides
- # a suggested initial path through the source when reviewing.
- #
- # Note: If you aren't reading this on https://github.com/jab/bidict, you may be
- # viewing an outdated version of the code. Please head to GitHub to review the
- # latest version, which contains important improvements over older versions.
- #
- # Thank you for reading and for any feedback you provide.
- # * Code review nav *
- #==============================================================================
- #← Prev: _orderedbase.py Current: _frozenordered.py Next: _orderedbidict.py →
- #==============================================================================
- """Provides :class:`FrozenOrderedBidict`, an immutable, hashable, ordered bidict."""
- from ._frozenbidict import frozenbidict
- from ._orderedbase import OrderedBidictBase
- from ._proxied import _ProxiedKeysVals
- from .compat import DICTS_ORDERED, PY2, izip
- # FrozenOrderedBidict intentionally does not subclass frozenbidict because it only complicates the
- # inheritance hierarchy without providing any actual code reuse: The only thing from frozenbidict
- # that FrozenOrderedBidict uses is frozenbidict.__hash__(), but Python specifically prevents
- # __hash__ from being inherited; it must instead always be defined explicitly as below. Users who
- # need an `is_frozenbidict(..)` test that succeeds for both frozenbidicts and FrozenOrderedBidicts
- # should therefore not use isinstance(foo, frozenbidict), but should instead use the appropriate
- # ABCs, e.g. `isinstance(foo, BidirectionalMapping) and not isinstance(foo, MutableMapping)`.
- class FrozenOrderedBidict(OrderedBidictBase):
- """Hashable, immutable, ordered bidict type."""
- __slots__ = ()
- # frozenbidict.__hash__ can be resued for FrozenOrderedBidict:
- # FrozenOrderedBidict inherits BidictBase.__eq__ which is order-insensitive,
- # and frozenbidict.__hash__ is consistent with BidictBase.__eq__.
- __hash__ = frozenbidict.__hash__ # Must define __hash__ explicitly, Python prevents inheriting
- if PY2:
- # Must grab the __func__ attribute off the method in Python 2, or else get "TypeError:
- # unbound method __hash__() must be called with frozenbidict instance as first argument"
- __hash__ = __hash__.__func__
- if DICTS_ORDERED:
- # If the Python implementation's dict type is ordered (e.g. PyPy or CPython >= 3.6), then
- # `FrozenOrderedBidict` can use the `_ProxiedKeysVals` mixin's more efficient implementations
- # of `keys` and `values`, rather than the less efficient implementations inherited from
- # `Mapping.keys` and `OrderedBidictBase.values`.
- # Both the `_fwdm` and `_invm` backing dicts will always be initialized with the provided
- # items in the correct order, and since `FrozenOrderedBidict` is immutable, their respective
- # orders can't get out of sync after a mutation, like they can with a mutable `OrderedBidict`.
- # (`FrozenOrderedBidict` can't use the more efficient `_ProxiedKeysValsItems.items`
- # implementation because the values in `_fwdm.items()` are nodes, so inheriting the
- # implementation from `Mapping.items` is the best we can do.)
- FrozenOrderedBidict.__bases__ = (_ProxiedKeysVals,) + FrozenOrderedBidict.__bases__
- if PY2:
- # We can do better than the `iteritems` implementation inherited from `Mapping`;
- # zipping together the keys from `_fwdm` and `_invm` runs faster (e.g. C speed on CPython).
- def iteritems(self):
- """An iterator over the contained items."""
- return izip(self._fwdm, self._invm) # pylint: disable=protected-access
- FrozenOrderedBidict.iteritems = iteritems
- # * Code review nav *
- #==============================================================================
- #← Prev: _orderedbase.py Current: _frozenordered.py Next: _orderedbidict.py →
- #==============================================================================
|