bazarr/libs/bidict/_mut.py

178 lines
6.6 KiB
Python
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# -*- 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 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: _frozenbidict.py Current: _mut.py Next: _bidict.py →
#==============================================================================
"""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`).
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)
def __delitem__(self, key):
u"""*x.__delitem__(y)  del x[y]*"""
self._pop(key)
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)
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)
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)
def clear(self):
"""Remove all items."""
self._fwdm.clear()
self._invm.clear()
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
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
def update(self, *args, **kw):
"""Like :meth:`putall` with default duplication policies."""
if args or kw:
self._update(False, None, *args, **kw)
def forceupdate(self, *args, **kw):
"""Like a bulk :meth:`forceput`."""
self._update(False, self._ON_DUP_OVERWRITE, *args, **kw)
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: _frozenbidict.py Current: _mut.py Next: _bidict.py →
#==============================================================================