Source code for bidict._mut

# -*- coding: utf-8 -*-
# Copyright 2009-2019 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

#                    * 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, 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:    Current:            Next: →

"""Provides :class:`bidict`."""

from ._base import BidictBase
from ._dup import OVERWRITE, RAISE, _OnDup
from ._miss import _MISS
from .compat import MutableMapping

# Extend MutableMapping explicitly because it doesn't implement __subclasshook__, as well as to
# inherit method implementations it provides that we can reuse (namely `setdefault`).
[docs]class MutableBidict(BidictBase, MutableMapping): """Base class for mutable bidirectional mappings.""" __slots__ = () __hash__ = None # since this class is mutable; explicit > implicit. _ON_DUP_OVERWRITE = _OnDup(key=OVERWRITE, val=OVERWRITE, kv=OVERWRITE)
[docs] def __delitem__(self, key): u"""*x.__delitem__(y) ⟺ del x[y]*""" self._pop(key)
[docs] def __setitem__(self, key, val): """ Set the value for *key* to *val*. If *key* is already associated with *val*, this is a no-op. If *key* is already associated with a different value, the old value will be replaced with *val*, as with dict's :meth:`__setitem__`. If *val* is already associated with a different key, an exception is raised to protect against accidental removal of the key that's currently associated with *val*. Use :meth:`put` instead if you want to specify different policy in the case that the provided key or value duplicates an existing one. Or use :meth:`forceput` to unconditionally associate *key* with *val*, replacing any existing items as necessary to preserve uniqueness. :raises bidict.ValueDuplicationError: if *val* duplicates that of an existing item. :raises bidict.KeyAndValueDuplicationError: if *key* duplicates the key of an existing item and *val* duplicates the value of a different existing item. """ on_dup = self._get_on_dup() self._put(key, val, on_dup)
[docs] def put(self, key, val, on_dup_key=RAISE, on_dup_val=RAISE, on_dup_kv=None): """ Associate *key* with *val* with the specified duplication policies. If *on_dup_kv* is ``None``, the *on_dup_val* policy will be used for it. For example, if all given duplication policies are :attr:`~bidict.RAISE`, then *key* will be associated with *val* if and only if *key* is not already associated with an existing value and *val* is not already associated with an existing key, otherwise an exception will be raised. If *key* is already associated with *val*, this is a no-op. :raises bidict.KeyDuplicationError: if attempting to insert an item whose key only duplicates an existing item's, and *on_dup_key* is :attr:`~bidict.RAISE`. :raises bidict.ValueDuplicationError: if attempting to insert an item whose value only duplicates an existing item's, and *on_dup_val* is :attr:`~bidict.RAISE`. :raises bidict.KeyAndValueDuplicationError: if attempting to insert an item whose key duplicates one existing item's, and whose value duplicates another existing item's, and *on_dup_kv* is :attr:`~bidict.RAISE`. """ on_dup = self._get_on_dup((on_dup_key, on_dup_val, on_dup_kv)) self._put(key, val, on_dup)
[docs] def forceput(self, key, val): """ Associate *key* with *val* unconditionally. Replace any existing mappings containing key *key* or value *val* as necessary to preserve uniqueness. """ self._put(key, val, self._ON_DUP_OVERWRITE)
[docs] def clear(self): """Remove all items.""" self._fwdm.clear() self._invm.clear()
[docs] def pop(self, key, default=_MISS): u"""*x.pop(k[, d]) → v* Remove specified key and return the corresponding value. :raises KeyError: if *key* is not found and no *default* is provided. """ try: return self._pop(key) except KeyError: if default is _MISS: raise return default
[docs] def popitem(self): u"""*x.popitem() → (k, v)* Remove and return some item as a (key, value) pair. :raises KeyError: if *x* is empty. """ if not self: raise KeyError('mapping is empty') key, val = self._fwdm.popitem() del self._invm[val] return key, val
[docs] def update(self, *args, **kw): """Like :meth:`putall` with default duplication policies.""" if args or kw: self._update(False, None, *args, **kw)
[docs] def forceupdate(self, *args, **kw): """Like a bulk :meth:`forceput`.""" self._update(False, self._ON_DUP_OVERWRITE, *args, **kw)
[docs] def putall(self, items, on_dup_key=RAISE, on_dup_val=RAISE, on_dup_kv=None): """ Like a bulk :meth:`put`. If one of the given items causes an exception to be raised, none of the items is inserted. """ if items: on_dup = self._get_on_dup((on_dup_key, on_dup_val, on_dup_kv)) self._update(False, on_dup, items)
# * Code review nav * #============================================================================== # ← Prev: Current: Next: → #==============================================================================