def test_frozendict_operator__ge__(self): for u in self.units: u_items_view = ItemsView(u.frz) for a in self.units: x = (u.frz >= a.frz) y = (u_items_view >= ItemsView(a.frz)) self.assertEqual(x, y)
def _init_inv(self): inv = object.__new__(self.__class__) inv.isinv = not self.isinv inv.fwd_cls = self.inv_cls inv.inv_cls = self.fwd_cls inv.fwdm = self.invm inv.invm = self.fwdm inv.itemsview = ItemsView(inv) inv.inv = self self.inv = inv
def __init__(self, *args, **kw): """Like dict's ``__init__``.""" self.isinv = getattr(args[0], 'isinv', False) if args else False self.fwdm = self.inv_cls() if self.isinv else self.fwd_cls() self.invm = self.fwd_cls() if self.isinv else self.inv_cls() self.itemsview = ItemsView(self) self._init_inv() # lgtm [py/init-calls-subclass] if args or kw: self._update(True, self.on_dup_key, self.on_dup_val, self.on_dup_kv, *args, **kw)
def default_enter(path, key, value): # print('enter(%r, %r)' % (key, value)) if isinstance(value, basestring): return value, False elif isinstance(value, Mapping): return value.__class__(), ItemsView(value) elif isinstance(value, Sequence): return value.__class__(), enumerate(value) elif isinstance(value, Set): return value.__class__(), enumerate(value) else: # files, strings, other iterables, and scalars are not # traversed return value, False
def items(self): """Set-like object providing a view of index items. >>> index = Index('/tmp/diskcache/index') >>> index.clear() >>> index.update({'a': 1, 'b': 2, 'c': 3}) >>> items_view = index.items() >>> ('b', 2) in items_view True :return: items view """ return ItemsView(self)
def default_enter(path, key, value): # print('enter(%r, %r)' % (key, value)) try: iter(value) except TypeError: return value, False if isinstance(value, basestring): return value, False elif isinstance(value, Mapping): return value.__class__(), ItemsView(value) elif isinstance(value, Sequence): return value.__class__(), enumerate(value) elif isinstance(value, Set): return value.__class__(), enumerate(value) return value, False
def _compute_hash(self): """ If :attr:`_USE_ITEMSVIEW_HASH` is ``True``, use the pure Python implementation of Python's frozenset hashing algorithm from ``collections.Set._hash`` to compute the hash incrementally in constant space. Otherwise, create an ephemeral frozenset out of the contained items and pass it to :func:`hash`. On CPython, this results in the faster ``frozenset_hash`` routine (implemented in ``setobject.c``) being used. CPython does not expose a way to use the fast C implementation of the algorithm without creating a frozenset. """ # ItemsView(self)._hash() is faster than combining # KeysView(self)._hash() with KeysView(self.inv)._hash(). if self._USE_ITEMSVIEW_HASH: return ItemsView(self)._hash() # frozenset(iteritems(self)) is faster than frozenset(ItemsView(self)). return hash(frozenset(iteritems(self)))
def viewitems(self): """Like :meth:`collections.OrderedDict.viewitems`.""" return ItemsView(self)
__dataclass_fields__ = () class NotAttrsItem(object): __attrs_attrs__ = () class HTML: def __html__(self): return "foo" UUID = uuid.uuid4() if sys.version_info[0] == 2: items_view = ItemsView({"foo": 1}) items_view_float = ItemsView({"foo": 1.333}) items_view_complex = ItemsView({1: 1.333, 2: ItemsView({2: 0.333})}) else: items_view = {"foo": 1}.items() items_view_float = {"foo": 1.333}.items() items_view_complex = {1: 1.333, 2: {2: 0.333}.items()}.items() @pytest.mark.parametrize( "value, expected, date_as_unix_time", ( ({1}, [1], False), (Decimal("1"), "1", False), (UUID, str(UUID), False), (datetime.datetime(2018, 1, 1), "2018-01-01T00:00:00", False),
def viewitems(self): """Like dict's ``viewitems``.""" return ItemsView(self)
def __hash__(self): """Return the hash of this bidict from its contained items.""" if getattr(self, '_hash', None) is None: # pylint: disable=protected-access # pylint: disable=protected-access,attribute-defined-outside-init self._hash = ItemsView(self)._hash() return self._hash
def data(self, weight=None): if weight is None: return ItemsView(self) return DataView(self, weight)
def __eq__(self, other): if not isinstance(other, (Message, Mapping)): return NotImplemented return dict(ItemsView(self)) == dict(ItemsView(other))
from abc import abstractproperty #: from itertools import izip #: # In Python 3, the collections ABCs were moved into collections.abc, which does not exist in # Python 2. Support for importing them directly from collections is dropped in Python 3.8. import collections as collections_abc # noqa: F401 (imported but unused) from collections import ( # noqa: F401 (imported but unused) Mapping, MutableMapping, KeysView, ValuesView, ItemsView) viewkeys = lambda m: m.viewkeys() if hasattr(m, 'viewkeys') else KeysView( m) #: viewvalues = lambda m: m.viewvalues() if hasattr(m, 'viewvalues' ) else ValuesView(m) #: viewitems = lambda m: m.viewitems() if hasattr(m, 'viewitems' ) else ItemsView(m) #: iterkeys = lambda m: m.iterkeys() if hasattr(m, 'iterkeys') else iter( m.keys()) #: itervalues = lambda m: m.itervalues() if hasattr( m, 'itervalues') else iter(m.values()) #: iteritems = lambda m: m.iteritems() if hasattr(m, 'iteritems') else iter( m.items()) #: else: # Assume Python 3 when not PY2, but explicitly check before showing this warning. if PYMAJOR == 3 and PYMINOR < 5: # pragma: no cover warn('Python3 < 3.5 is not officially supported.') import collections.abc as collections_abc # noqa: F401 (imported but unused) from collections.abc import ( # noqa: F401 (imported but unused)
def data(self): return ItemsView(self)
class BidictBase(BidirectionalMapping): """ Base class for all provided bidirectional map types. Mutable and immutable bidict types extend this class, which implements all the shared logic. Users will typically only interact with subclasses of this class. .. py:attribute:: _fwd The backing one-way dict for the forward items. .. py:attribute:: _inv The backing one-way dict for inverse items. .. py:attribute:: _fwd_class The Mapping type used for the backing _fwd dict. .. py:attribute:: _inv_class The Mapping type used for the backing _inv dict. .. py:attribute:: _isinv :class:`bool` representing whether this bidict is the inverse of some other bidict which has already been created. If True, the meaning of :attr:`_fwd_class` and :attr:`_inv_class` is swapped. This enables the inverse of a bidict specifying a different :attr:`_fwd_class` and :attr:`_inv_class` to be passed back into its constructor such that the resulting copy has its :attr:`_fwd_class` and :attr:`_inv_class` set correctly. .. py:attribute:: _on_dup_key :class:`DuplicationBehavior` in the event of a key duplication. .. py:attribute:: _on_dup_val :class:`DuplicationBehavior` in the event of a value duplication. .. py:attribute:: _on_dup_kv :class:`DuplicationBehavior` in the event of key and value duplication. """ _on_dup_key = OVERWRITE _on_dup_val = RAISE _on_dup_kv = RAISE _fwd_class = dict _inv_class = dict def __init__(self, *args, **kw): """Like dict's ``__init__``.""" self._isinv = getattr(args[0], '_isinv', False) if args else False self._fwd = self._inv_class() if self._isinv else self._fwd_class() self._inv = self._fwd_class() if self._isinv else self._inv_class() self._init_inv() if args or kw: self._update(True, self._on_dup_key, self._on_dup_val, self._on_dup_kv, *args, **kw) def _init_inv(self): inv = object.__new__(self.__class__) inv._isinv = not self._isinv inv._fwd_class = self._inv_class inv._inv_class = self._fwd_class inv._fwd = self._inv inv._inv = self._fwd inv.__inv = self self.__inv = inv @property def inv(self): """The inverse bidict.""" return self.__inv def __repr__(self): s = self.__class__.__name__ + '(' if not self: return s + ')' # If we have a truthy __reversed__ attribute, use an ordered repr. # (Python doesn't provide an Ordered or OrderedMapping ABC, else we'd # use that. Must use getattr rather than hasattr since __reversed__ # may be set to None, which signifies non-ordered/-reversible.) if getattr(self, '__reversed__', None): return s + '[' + ', '.join(repr(i) for i in iteritems(self)) + '])' return s + '{' + ', '.join('%r: %r' % i for i in iteritems(self)) + '})' def __eq__(self, other): # This should be faster than using Mapping.__eq__'s implementation. return self._fwd == other def _pop(self, key): val = self._fwd.pop(key) del self._inv[val] return val def _clear(self): self._fwd.clear() self._inv.clear() def _put(self, key, val, on_dup_key, on_dup_val, on_dup_kv): result = self._dedup_item(key, val, on_dup_key, on_dup_val, on_dup_kv) if result: self._write_item(key, val, *result) def _dedup_item(self, key, val, on_dup_key, on_dup_val, on_dup_kv): """ Check *key* and *val* for any duplication in self. Handle any duplication as per the given duplication behaviors. (key, val) already present is construed as a no-op, not a duplication. If duplication is found and the corresponding duplication behavior is *RAISE*, raise the appropriate error. If duplication is found and the corresponding duplication behavior is *IGNORE*, return *None*. If duplication is found and the corresponding duplication behavior is *OVERWRITE*, or if no duplication is found, return the dedup result *(isdupkey, isdupval, invbyval, fwdbykey)*. """ fwd = self._fwd inv = self._inv fwdbykey = fwd.get(key, _missing) invbyval = inv.get(val, _missing) isdupkey = fwdbykey is not _missing isdupval = invbyval is not _missing if isdupkey and isdupval: if self._isdupitem(key, val, invbyval, fwdbykey): # (key, val) duplicates an existing item -> no-op. return # key and val each duplicate a different existing item. if on_dup_kv is RAISE: raise KeyAndValueDuplicationError(key, val) elif on_dup_kv is IGNORE: return # else on_dup_kv is OVERWRITE. Fall through to return on last line. elif isdupkey: if on_dup_key is RAISE: raise KeyDuplicationError(key) elif on_dup_key is IGNORE: return # else on_dup_key is OVERWRITE. Fall through to return on last line. elif isdupval: if on_dup_val is RAISE: raise ValueDuplicationError(val) elif on_dup_val is IGNORE: return # else on_dup_val is OVERWRITE. Fall through to return on last line. # else neither isdupkey nor isdupval. return isdupkey, isdupval, invbyval, fwdbykey def _isdupitem(self, key, val, oldkey, oldval): dup = oldkey == key assert dup == (oldval == val) return dup def _write_item(self, key, val, isdupkey, isdupval, oldkey, oldval): self._fwd[key] = val self._inv[val] = key if isdupkey: del self._inv[oldval] if isdupval: del self._fwd[oldkey] return key, val, isdupkey, isdupval, oldkey, oldval def _update(self, init, on_dup_key, on_dup_val, on_dup_kv, *args, **kw): if not args and not kw: return if on_dup_kv is ON_DUP_VAL: on_dup_kv = on_dup_val rollbackonfail = not init or RAISE in (on_dup_key, on_dup_val, on_dup_kv) if rollbackonfail: return self._update_rbf(on_dup_key, on_dup_val, on_dup_kv, *args, **kw) _put = self._put for (key, val) in pairs(*args, **kw): _put(key, val, on_dup_key, on_dup_val, on_dup_kv) def _update_rbf(self, on_dup_key, on_dup_val, on_dup_kv, *args, **kw): """Update, rolling back on failure.""" exc = None writes = [] appendwrite = writes.append dedup_item = self._dedup_item write_item = self._write_item for (key, val) in pairs(*args, **kw): try: dedup_result = dedup_item(key, val, on_dup_key, on_dup_val, on_dup_kv) except DuplicationError as e: exc = e break if dedup_result: write_result = write_item(key, val, *dedup_result) appendwrite(write_result) if exc: undo_write = self._undo_write for write in reversed(writes): undo_write(*write) raise exc def _undo_write(self, key, val, isdupkey, isdupval, oldkey, oldval): fwd = self._fwd inv = self._inv if not isdupkey and not isdupval: self._pop(key) return if isdupkey: fwd[key] = oldval inv[oldval] = key if not isdupval: del inv[val] if isdupval: inv[val] = oldkey fwd[oldkey] = val if not isdupkey: del fwd[key] def copy(self): """Like :py:meth:`dict.copy`.""" # This should be faster than ``return self.__class__(self)`` because # it avoids the unnecessary duplicate checking. copy = object.__new__(self.__class__) copy._isinv = self._isinv copy._fwd = self._fwd.copy() copy._inv = self._inv.copy() cinv = object.__new__(self.__class__) cinv._isinv = not self._isinv cinv._fwd_class = self._inv_class cinv._inv_class = self._fwd_class cinv._fwd = copy._inv cinv._inv = copy._fwd cinv.__inv = copy copy.__inv = cinv return copy __copy__ = copy __len__ = _proxied('__len__') __iter__ = _proxied('__iter__') __getitem__ = _proxied('__getitem__') values = _proxied('keys', attrname='inv') values.__doc__ = \ "B.values() -> a set-like object providing a view on B's values.\n\n" \ 'Note that because values of a BidirectionalMapping are also keys\n' \ 'of its inverse, this returns a *KeysView* object rather than a\n' \ '*ValuesView* object, conferring set-like benefits.' if PY2: # pragma: no cover viewkeys = _proxied('viewkeys') viewvalues = _proxied('viewkeys', attrname='inv', doc=values.__doc__.replace( 'values()', 'viewvalues()')) values.__doc__ = "Like dict's ``values``." # Use ItemsView here rather than proxying to _fwd.viewitems() so that # OrderedBidictBase (whose _fwd's values are nodes, not bare values) # can use it. viewitems = lambda self: ItemsView(self)
def items(self) -> ItemsView: return ItemsView(self)
def items(self): "implementation of a view, from collections.Mapping" return ItemsView(self)
def items(self): return ItemsView(self)
def _items_proxy(self, getter): for u in self.units: items = getter(u.frz) self.assertRaises(TypeError, itemgetter(0), items) self.assertEqual(items, ItemsView(u.frz))
def items(self): "D.items() -> a set-like object providing a view on D's items" return ItemsView(self)
def items(message: Message) -> ItemsView: return ItemsView(message)
def viewitems(self): "OMD.viewitems() -> a set-like object providing a view on OMD's items" return ItemsView(self)
def items(self): """ Get all the items of the configuration (key/value pairs). :return tuple: The items of the configuration. """ return ItemsView(self)