예제 #1
0
파일: _helpers.py 프로젝트: alx-/pyrsistent
def freeze(o):
    """
    Recursively convert simple Python containers into pyrsistent versions
    of those containers.

    - list is converted to pvector, recursively
    - dict is converted to pmap, recursively on values (but not keys)
    - set is converted to pset, but not recursively
    - tuple is converted to tuple, recursively.

    Sets and dict keys are not recursively frozen because they do not contain
    mutable data by convention. The main exception to this rule is that
    dict keys and set elements are often instances of mutable objects that
    support hash-by-id, which this function can't convert anyway.

    >>> freeze(set([1, 2]))
    pset([1, 2])
    >>> freeze([1, {'a': 3}])
    pvector([1, pmap({'a': 3})])
    >>> freeze((1, []))
    (1, pvector([]))
    """
    typ = type(o)
    if typ is dict:
        return pmap(dict((k, freeze(v)) for k, v in six.iteritems(o)))
    if typ is list:
        return pvector(map(freeze, o))
    if typ is tuple:
        return tuple(map(freeze, o))
    if typ is set:
        return pset(o)
    return o
예제 #2
0
def freeze(o):
    """
    Recursively convert simple Python containers into pyrsistent versions
    of those containers.

    - list is converted to pvector, recursively
    - dict is converted to pmap, recursively on values (but not keys)
    - set is converted to pset, but not recursively
    - tuple is converted to tuple, recursively.

    Sets and dict keys are not recursively frozen because they do not contain
    mutable data by convention. The main exception to this rule is that
    dict keys and set elements are often instances of mutable objects that
    support hash-by-id, which this function can't convert anyway.

    >>> freeze(set([1, 2]))
    pset([1, 2])
    >>> freeze([1, {'a': 3}])
    pvector([1, pmap({'a': 3})])
    >>> freeze((1, []))
    (1, pvector([]))
    """
    typ = type(o)
    if typ is dict:
        return pmap(dict((k, freeze(v)) for k, v in six.iteritems(o)))
    if typ is list:
        return pvector(map(freeze, o))
    if typ is tuple:
        return tuple(map(freeze, o))
    if typ is set:
        return pset(o)
    return o
예제 #3
0
    def __new__(cls, **kwargs):
        # Hack total! If these two special attributes exist that means we can create
        # ourselves. Otherwise we need to go through the Evolver to create the structures
        # for us.
        if "_precord_size" in kwargs and "_precord_buckets" in kwargs:
            return super(PRecord, cls).__new__(
                cls, kwargs["_precord_size"], kwargs["_precord_buckets"]
            )

        factory_fields = kwargs.pop("_factory_fields", None)
        ignore_extra = kwargs.pop("_ignore_extra", False)

        initial_values = kwargs
        if cls._precord_initial_values:
            initial_values = dict(
                (k, v() if callable(v) else v)
                for k, v in cls._precord_initial_values.items()
            )
            initial_values.update(kwargs)

        e = _PRecordEvolver(
            cls, pmap(), _factory_fields=factory_fields, _ignore_extra=ignore_extra
        )
        for k, v in initial_values.items():
            e[k] = v

        return e.persistent()
예제 #4
0
    def __new__(cls, initial={}, size=_UNDEFINED_CHECKED_PMAP_SIZE):
        if size is not _UNDEFINED_CHECKED_PMAP_SIZE:
            return super(CheckedPMap, cls).__new__(cls, size, initial)

        evolver = CheckedPMap.Evolver(cls, pmap())
        for k, v in initial.items():
            evolver.set(k, v)

        return evolver.persistent()
예제 #5
0
    def __new__(cls, initial={}, size=_UNDEFINED_CHECKED_PMAP_SIZE):
        if size is not _UNDEFINED_CHECKED_PMAP_SIZE:
            return super(CheckedPMap, cls).__new__(cls, size, initial)

        evolver = CheckedPMap.Evolver(cls, pmap())
        for k, v in initial.items():
            evolver.set(k, v)

        return evolver.persistent()
예제 #6
0
def pbag(elements):
    """
    Convert an iterable to a persistent bag.

    Takes an iterable with elements to insert.

    >>> pbag([1, 2, 3, 2])
    pbag([1, 2, 2, 3])
    """
    if not elements:
        return _EMPTY_PBAG
    return PBag(reduce(_add_to_counters, elements, pmap()))
예제 #7
0
def pbag(elements):
    """
    Convert an iterable to a persistent bag.

    Takes an iterable with elements to insert.

    >>> pbag([1, 2, 3, 2])
    pbag([1, 2, 2, 3])
    """
    if not elements:
        return _EMPTY_PBAG
    return PBag(reduce(_add_to_counters, elements, pmap()))
예제 #8
0
def _update_structure(structure, kvs, path, command):
    from pyrsistent._pmap import pmap
    e = structure.evolver()
    if not path and command is discard:
        # Do this in reverse to avoid index problems with vectors. See #92.
        for k, v in reversed(kvs):
            discard(e, k)
    else:
        for k, v in kvs:
            result = _do_to_path(v, path, command)
            if command is pmap() or result is not v:
                e[k] = result

    return e.persistent()
예제 #9
0
파일: _pbag.py 프로젝트: sarum90/pyrsistent
 def __and__(self, other):
     """
     Intersection: Only keep elements that are present in both PBags.
     
     >>> pbag([1, 2, 2, 2]) & pbag([2, 3, 3])
     pbag([2])
     """
     if not isinstance(other, PBag):
         return NotImplemented
     result = pmap().evolver()
     for elem, count in self._counts.iteritems():
         newcount = min(count, other.count(elem))
         if newcount > 0:
             result[elem] = newcount
     return PBag(result.persistent())
예제 #10
0
 def __and__(self, other):
     """
     Intersection: Only keep elements that are present in both PBags.
     
     >>> pbag([1, 2, 2, 2]) & pbag([2, 3, 3])
     pbag([2])
     """
     if not isinstance(other, PBag):
         return NotImplemented
     result = pmap().evolver()
     for elem, count in self._counts.iteritems():
         newcount = min(count, other.count(elem))
         if newcount > 0:
             result[elem] = newcount
     return PBag(result.persistent())
예제 #11
0
    def __new__(cls, **kwargs):
        # Hack total! If these two special attributes exist that means we can create
        # ourselves. Otherwise we need to go through the Evolver to create the structures
        # for us.
        if '_precord_size' in kwargs and '_precord_buckets' in kwargs:
            return super(PRecord, cls).__new__(cls, kwargs['_precord_size'], kwargs['_precord_buckets'])

        initial_values = kwargs
        if cls._precord_initial_values:
            initial_values = dict(cls._precord_initial_values)
            initial_values.update(kwargs)

        e = _PRecordEvolver(cls, pmap())
        for k, v in initial_values.items():
            e[k] = v

        return e.persistent()
예제 #12
0
def _get_keys_and_values(structure, key_spec):
    from pyrsistent._pmap import pmap
    if callable(key_spec):
        # Support predicates as callable objects in the path
        arity = _get_arity(key_spec)
        if arity == 1:
            # Unary predicates are called with the "key" of the path
            # - eg a key in a mapping, an index in a sequence.
            return [(k, v) for k, v in _items(structure) if key_spec(k)]
        elif arity == 2:
            # Binary predicates are called with the key and the corresponding
            # value.
            return [(k, v) for k, v in _items(structure) if key_spec(k, v)]
        else:
            # Other arities are an error.
            raise ValueError(
                "callable in transform path must take 1 or 2 arguments")

    # Non-callables are used as-is as a key.
    return [(key_spec, _get(structure, key_spec, pmap()))]
예제 #13
0
    def __new__(cls, **kwargs):
        # Hack total! If these two special attributes exist that means we can create
        # ourselves. Otherwise we need to go through the Evolver to create the structures
        # for us.
        if '_precord_size' in kwargs and '_precord_buckets' in kwargs:
            return super(PRecord, cls).__new__(cls, kwargs['_precord_size'], kwargs['_precord_buckets'])

        factory_fields = kwargs.pop('_factory_fields', None)
        ignore_extra = kwargs.pop('_ignore_extra', False)

        initial_values = kwargs
        if cls._precord_initial_values:
            initial_values = dict((k, v() if callable(v) else v)
                                  for k, v in cls._precord_initial_values.items())
            initial_values.update(kwargs)

        e = _PRecordEvolver(cls, pmap(), _factory_fields=factory_fields, _ignore_extra=ignore_extra)
        for k, v in initial_values.items():
            e[k] = v

        return e.persistent()
예제 #14
0
def _update_structure(structure, kvs, path, command):
    from pyrsistent._pmap import pmap
    e = structure.evolver()
    if not path and command is discard:
        # Do this in reverse to avoid index problems with vectors. See #92.
        for k, v in reversed(kvs):
            discard(e, k)
    else:
        for k, v in kvs:
            is_empty = False
            if v is _EMPTY_SENTINEL:
                # Allow expansion of structure but make sure to cover the case
                # when an empty pmap is added as leaf node. See #154.
                is_empty = True
                v = pmap()

            result = _do_to_path(v, path, command)
            if result is not v or is_empty:
                e[k] = result

    return e.persistent()
예제 #15
0
def freeze(o, strict=True):
    """
    Recursively convert simple Python containers into pyrsistent versions
    of those containers.

    - list is converted to pvector, recursively
    - dict is converted to pmap, recursively on values (but not keys)
    - set is converted to pset, but not recursively
    - tuple is converted to tuple, recursively.

    If strict == True (default):

    - freeze is called on elements of pvectors
    - freeze is called on values of pmaps

    Sets and dict keys are not recursively frozen because they do not contain
    mutable data by convention. The main exception to this rule is that
    dict keys and set elements are often instances of mutable objects that
    support hash-by-id, which this function can't convert anyway.

    >>> freeze(set([1, 2]))
    pset([1, 2])
    >>> freeze([1, {'a': 3}])
    pvector([1, pmap({'a': 3})])
    >>> freeze((1, []))
    (1, pvector([]))
    """
    typ = type(o)
    if typ is dict or (strict and isinstance(o, PMap)):
        return pmap({k: freeze(v, strict) for k, v in o.items()})
    if typ is list or (strict and isinstance(o, PVector)):
        curried_freeze = lambda x: freeze(x, strict)
        return pvector(map(curried_freeze, o))
    if typ is tuple:
        curried_freeze = lambda x: freeze(x, strict)
        return tuple(map(curried_freeze, o))
    if typ is set:
        # impossible to have anything that needs freezing inside a set or pset
        return pset(o)
    return o
예제 #16
0
파일: _pset.py 프로젝트: tobgu/pyrsistent
 def _from_iterable(cls, it, pre_size=8):
     return PSet(pmap(dict((k, True) for k in it), pre_size=pre_size))
예제 #17
0
파일: _pset.py 프로젝트: tobgu/pyrsistent
    __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)
예제 #18
0
def _get_keys_and_values(structure, key_spec):
    from pyrsistent._pmap import pmap
    if callable(key_spec):
        return [(k, v) for k, v in _items(structure) if key_spec(k)]

    return [(key_spec, _get(structure, key_spec, pmap()))]
예제 #19
0

def b(*elements):
    """
    Construct a persistent bag.

    Takes an arbitrary number of arguments to insert into the new persistent
    bag.

    >>> b(1, 2, 3, 2)
    pbag([1, 2, 2, 3])
    """
    return pbag(elements)


def pbag(elements):
    """
    Convert an iterable to a persistent bag.

    Takes an iterable with elements to insert.

    >>> pbag([1, 2, 3, 2])
    pbag([1, 2, 2, 3])
    """
    if not elements:
        return _EMPTY_PBAG
    return PBag(reduce(_add_to_counters, elements, pmap()))


_EMPTY_PBAG = PBag(pmap())
예제 #20
0
 def _from_iterable(cls, it, pre_size=8):
     return PSet(pmap(dict((k, True) for k in it), pre_size=pre_size))
예제 #21
0
    __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)
예제 #22
0

def b(*elements):
    """
    Construct a persistent bag.

    Takes an arbitrary number of arguments to insert into the new persistent
    bag.

    >>> b(1, 2, 3, 2)
    pbag([1, 2, 2, 3])
    """
    return pbag(elements)


def pbag(elements):
    """
    Convert an iterable to a persistent bag.

    Takes an iterable with elements to insert.

    >>> pbag([1, 2, 3, 2])
    pbag([1, 2, 2, 3])
    """
    if not elements:
        return _EMPTY_PBAG
    return PBag(reduce(_add_to_counters, elements, pmap()))


_EMPTY_PBAG = PBag(pmap())
예제 #23
0
def _get_keys_and_values(structure, key_spec):
    from pyrsistent._pmap import pmap
    if callable(key_spec):
        return [(k, v) for k, v in _items(structure) if key_spec(k)]

    return [(key_spec, _get(structure, key_spec, pmap()))]