2021-05-08 22:25:29 +08:00
|
|
|
# -*- coding: utf-8 -*-
|
2022-01-24 12:07:52 +08:00
|
|
|
# Copyright 2009-2021 Joshua Bronson. All Rights Reserved.
|
2021-05-08 22:25:29 +08:00
|
|
|
#
|
|
|
|
# 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: __init__.py Current: _abc.py Next: _base.py →
|
|
|
|
#==============================================================================
|
|
|
|
|
|
|
|
|
2022-01-24 12:07:52 +08:00
|
|
|
"""Provide the :class:`BidirectionalMapping` abstract base class."""
|
2021-05-08 22:25:29 +08:00
|
|
|
|
2022-01-24 12:07:52 +08:00
|
|
|
import typing as _t
|
|
|
|
from abc import abstractmethod
|
2021-05-08 22:25:29 +08:00
|
|
|
|
2022-01-24 12:07:52 +08:00
|
|
|
from ._typing import KT, VT
|
2021-05-08 22:25:29 +08:00
|
|
|
|
2022-01-24 12:07:52 +08:00
|
|
|
|
|
|
|
class BidirectionalMapping(_t.Mapping[KT, VT]):
|
2021-05-08 22:25:29 +08:00
|
|
|
"""Abstract base class (ABC) for bidirectional mapping types.
|
|
|
|
|
|
|
|
Extends :class:`collections.abc.Mapping` primarily by adding the
|
|
|
|
(abstract) :attr:`inverse` property,
|
|
|
|
which implementors of :class:`BidirectionalMapping`
|
|
|
|
should override to return a reference to the inverse
|
|
|
|
:class:`BidirectionalMapping` instance.
|
|
|
|
"""
|
|
|
|
|
|
|
|
__slots__ = ()
|
|
|
|
|
2022-01-24 12:07:52 +08:00
|
|
|
@property
|
|
|
|
@abstractmethod
|
|
|
|
def inverse(self) -> 'BidirectionalMapping[VT, KT]':
|
2021-05-08 22:25:29 +08:00
|
|
|
"""The inverse of this bidirectional mapping instance.
|
|
|
|
|
|
|
|
*See also* :attr:`bidict.BidictBase.inverse`, :attr:`bidict.BidictBase.inv`
|
|
|
|
|
|
|
|
:raises NotImplementedError: Meant to be overridden in subclasses.
|
|
|
|
"""
|
|
|
|
# The @abstractproperty decorator prevents BidirectionalMapping subclasses from being
|
|
|
|
# instantiated unless they override this method. So users shouldn't be able to get to the
|
|
|
|
# point where they can unintentionally call this implementation of .inverse on something
|
|
|
|
# anyway. Could leave the method body empty, but raise NotImplementedError so it's extra
|
|
|
|
# clear there's no reason to call this implementation (e.g. via super() after overriding).
|
|
|
|
raise NotImplementedError
|
|
|
|
|
2022-01-24 12:07:52 +08:00
|
|
|
def __inverted__(self) -> _t.Iterator[_t.Tuple[VT, KT]]:
|
2021-05-08 22:25:29 +08:00
|
|
|
"""Get an iterator over the items in :attr:`inverse`.
|
|
|
|
|
|
|
|
This is functionally equivalent to iterating over the items in the
|
|
|
|
forward mapping and inverting each one on the fly, but this provides a
|
|
|
|
more efficient implementation: Assuming the already-inverted items
|
|
|
|
are stored in :attr:`inverse`, just return an iterator over them directly.
|
|
|
|
|
|
|
|
Providing this default implementation enables external functions,
|
|
|
|
particularly :func:`~bidict.inverted`, to use this optimized
|
|
|
|
implementation when available, instead of having to invert on the fly.
|
|
|
|
|
|
|
|
*See also* :func:`bidict.inverted`
|
|
|
|
"""
|
2022-01-24 12:07:52 +08:00
|
|
|
return iter(self.inverse.items())
|
|
|
|
|
|
|
|
def values(self) -> _t.KeysView[VT]: # type: ignore [override] # https://github.com/python/typeshed/issues/4435
|
|
|
|
"""A set-like object providing a view on the contained values.
|
|
|
|
|
|
|
|
Override the implementation inherited from
|
|
|
|
:class:`~collections.abc.Mapping`.
|
|
|
|
Because the values of a :class:`~bidict.BidirectionalMapping`
|
|
|
|
are the keys of its inverse,
|
|
|
|
this returns a :class:`~collections.abc.KeysView`
|
|
|
|
rather than a :class:`~collections.abc.ValuesView`,
|
|
|
|
which has the advantages of constant-time containment checks
|
|
|
|
and supporting set operations.
|
|
|
|
"""
|
|
|
|
return self.inverse.keys() # type: ignore [return-value]
|
|
|
|
|
|
|
|
|
|
|
|
class MutableBidirectionalMapping(BidirectionalMapping[KT, VT], _t.MutableMapping[KT, VT]):
|
|
|
|
"""Abstract base class (ABC) for mutable bidirectional mapping types."""
|
|
|
|
|
|
|
|
__slots__ = ()
|
2021-05-08 22:25:29 +08:00
|
|
|
|
|
|
|
|
|
|
|
# * Code review nav *
|
|
|
|
#==============================================================================
|
|
|
|
# ← Prev: __init__.py Current: _abc.py Next: _base.py →
|
|
|
|
#==============================================================================
|