201 lines
5.7 KiB
Python
201 lines
5.7 KiB
Python
# uncompyle6 version 3.9.2
|
|
# Python bytecode version base 3.7.0 (3394)
|
|
# Decompiled from: Python 3.8.19 (default, Mar 20 2024, 15:27:52)
|
|
# [Clang 14.0.6 ]
|
|
# Embedded file name: /var/user/app/device_supervisorbak/device_supervisor/lib/pyrsistent/_pset.py
|
|
# Compiled at: 2024-04-18 03:12:57
|
|
# Size of source mod 2**32: 5718 bytes
|
|
from ._compat import Set, Hashable
|
|
import sys
|
|
from pyrsistent._pmap import pmap
|
|
PY2 = sys.version_info[0] < 3
|
|
|
|
class PSet(object):
|
|
__doc__ = "\n Persistent set implementation. Built on top of the persistent map. The set supports all operations\n in the Set protocol and is Hashable.\n\n Do not instantiate directly, instead use the factory functions :py:func:`s` or :py:func:`pset`\n to create an instance.\n\n Random access and insert is log32(n) where n is the size of the set.\n\n Some examples:\n\n >>> s = pset([1, 2, 3, 1])\n >>> s2 = s.add(4)\n >>> s3 = s2.remove(2)\n >>> s\n pset([1, 2, 3])\n >>> s2\n pset([1, 2, 3, 4])\n >>> s3\n pset([1, 3, 4])\n "
|
|
__slots__ = ('_map', '__weakref__')
|
|
|
|
def __new__(cls, m):
|
|
self = super(PSet, cls).__new__(cls)
|
|
self._map = m
|
|
return self
|
|
|
|
def __contains__(self, element):
|
|
return element in self._map
|
|
|
|
def __iter__(self):
|
|
return iter(self._map)
|
|
|
|
def __len__(self):
|
|
return len(self._map)
|
|
|
|
def __repr__(self):
|
|
return PY2 or self or "p" + str(set(self))
|
|
return "pset([{0}])".format(str(set(self))[1[:-1]])
|
|
|
|
def __str__(self):
|
|
return self.__repr__()
|
|
|
|
def __hash__(self):
|
|
return hash(self._map)
|
|
|
|
def __reduce__(self):
|
|
return (
|
|
pset, (list(self),))
|
|
|
|
@classmethod
|
|
def _from_iterable(cls, it, pre_size=8):
|
|
return PSet(pmap((dict(((k, True) for k in it))), pre_size=pre_size))
|
|
|
|
def add(self, element):
|
|
"""
|
|
Return a new PSet with element added
|
|
|
|
>>> s1 = s(1, 2)
|
|
>>> s1.add(3)
|
|
pset([1, 2, 3])
|
|
"""
|
|
return self.evolver().add(element).persistent()
|
|
|
|
def update(self, iterable):
|
|
"""
|
|
Return a new PSet with elements in iterable added
|
|
|
|
>>> s1 = s(1, 2)
|
|
>>> s1.update([3, 4, 4])
|
|
pset([1, 2, 3, 4])
|
|
"""
|
|
e = self.evolver()
|
|
for element in iterable:
|
|
e.add(element)
|
|
|
|
return e.persistent()
|
|
|
|
def remove(self, element):
|
|
"""
|
|
Return a new PSet with element removed. Raises KeyError if element is not present.
|
|
|
|
>>> s1 = s(1, 2)
|
|
>>> s1.remove(2)
|
|
pset([1])
|
|
"""
|
|
if element in self._map:
|
|
return self.evolver().remove(element).persistent()
|
|
raise KeyError("Element '%s' not present in PSet" % element)
|
|
|
|
def discard(self, element):
|
|
"""
|
|
Return a new PSet with element removed. Returns itself if element is not present.
|
|
"""
|
|
if element in self._map:
|
|
return self.evolver().remove(element).persistent()
|
|
return self
|
|
|
|
class _Evolver(object):
|
|
__slots__ = ('_original_pset', '_pmap_evolver')
|
|
|
|
def __init__(self, original_pset):
|
|
self._original_pset = original_pset
|
|
self._pmap_evolver = original_pset._map.evolver()
|
|
|
|
def add(self, element):
|
|
self._pmap_evolver[element] = True
|
|
return self
|
|
|
|
def remove(self, element):
|
|
del self._pmap_evolver[element]
|
|
return self
|
|
|
|
def is_dirty(self):
|
|
return self._pmap_evolver.is_dirty()
|
|
|
|
def persistent(self):
|
|
if not self.is_dirty():
|
|
return self._original_pset
|
|
return PSet(self._pmap_evolver.persistent())
|
|
|
|
def __len__(self):
|
|
return len(self._pmap_evolver)
|
|
|
|
def copy(self):
|
|
return self
|
|
|
|
def evolver(self):
|
|
"""
|
|
Create a new evolver for this pset. For a discussion on evolvers in general see the
|
|
documentation for the pvector evolver.
|
|
|
|
Create the evolver and perform various mutating updates to it:
|
|
|
|
>>> s1 = s(1, 2, 3)
|
|
>>> e = s1.evolver()
|
|
>>> _ = e.add(4)
|
|
>>> len(e)
|
|
4
|
|
>>> _ = e.remove(1)
|
|
|
|
The underlying pset remains the same:
|
|
|
|
>>> s1
|
|
pset([1, 2, 3])
|
|
|
|
The changes are kept in the evolver. An updated pmap can be created using the
|
|
persistent() function on the evolver.
|
|
|
|
>>> s2 = e.persistent()
|
|
>>> s2
|
|
pset([2, 3, 4])
|
|
|
|
The new pset will share data with the original pset in the same way that would have
|
|
been done if only using operations on the pset.
|
|
"""
|
|
return PSet._Evolver(self)
|
|
|
|
__le__ = Set.__le__
|
|
__lt__ = Set.__lt__
|
|
__gt__ = Set.__gt__
|
|
__ge__ = Set.__ge__
|
|
__eq__ = Set.__eq__
|
|
__ne__ = Set.__ne__
|
|
__and__ = Set.__and__
|
|
__or__ = Set.__or__
|
|
__sub__ = Set.__sub__
|
|
__xor__ = Set.__xor__
|
|
issubset = __le__
|
|
issuperset = __ge__
|
|
union = __or__
|
|
intersection = __and__
|
|
difference = __sub__
|
|
symmetric_difference = __xor__
|
|
isdisjoint = Set.isdisjoint
|
|
|
|
|
|
Set.register(PSet)
|
|
Hashable.register(PSet)
|
|
_EMPTY_PSET = PSet(pmap())
|
|
|
|
def pset(iterable=(), pre_size=8):
|
|
"""
|
|
Creates a persistent set from iterable. Optionally takes a sizing parameter equivalent to that
|
|
used for :py:func:`pmap`.
|
|
|
|
>>> s1 = pset([1, 2, 3, 2])
|
|
>>> s1
|
|
pset([1, 2, 3])
|
|
"""
|
|
if not iterable:
|
|
return _EMPTY_PSET
|
|
return PSet._from_iterable(iterable, pre_size=pre_size)
|
|
|
|
|
|
def s(*elements):
|
|
"""
|
|
Create a persistent set.
|
|
|
|
Takes an arbitrary number of arguments to insert into the new set.
|
|
|
|
>>> s1 = s(1, 2, 3, 2)
|
|
>>> s1
|
|
pset([1, 2, 3])
|
|
"""
|
|
return pset(elements)
|