Exemplo n.º 1
0
 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)
Exemplo n.º 2
0
 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
Exemplo n.º 3
0
 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
Exemplo n.º 5
0
        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)
Exemplo n.º 6
0
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
Exemplo n.º 7
0
    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)))
Exemplo n.º 8
0
 def viewitems(self):
     """Like :meth:`collections.OrderedDict.viewitems`."""
     return ItemsView(self)
Exemplo n.º 9
0
    __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),
Exemplo n.º 10
0
 def viewitems(self):
     """Like dict's ``viewitems``."""
     return ItemsView(self)
Exemplo n.º 11
0
 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
Exemplo n.º 12
0
 def data(self, weight=None):
     if weight is None:
         return ItemsView(self)
     return DataView(self, weight)
Exemplo n.º 13
0
 def __eq__(self, other):
     if not isinstance(other, (Message, Mapping)):
         return NotImplemented
     return dict(ItemsView(self)) == dict(ItemsView(other))
Exemplo n.º 14
0
    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)
Exemplo n.º 15
0
 def data(self):
     return ItemsView(self)
Exemplo n.º 16
0
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)
Exemplo n.º 17
0
 def items(self) -> ItemsView:
     return ItemsView(self)
Exemplo n.º 18
0
 def items(self):
     "implementation of a view, from collections.Mapping"
     return ItemsView(self)
Exemplo n.º 19
0
 def items(self):
     return ItemsView(self)
Exemplo n.º 20
0
 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))
Exemplo n.º 21
0
 def items(self):
     "D.items() -> a set-like object providing a view on D's items"
     return ItemsView(self)
Exemplo n.º 22
0
def items(message: Message) -> ItemsView:
    return ItemsView(message)
Exemplo n.º 23
0
 def viewitems(self):
     "OMD.viewitems() -> a set-like object providing a view on OMD's items"
     return ItemsView(self)
Exemplo n.º 24
0
 def items(self):
     """
     Get all the items of the configuration (key/value pairs).
     :return tuple: The items of the configuration.
     """
     return ItemsView(self)