snakeoil.containers module

Container classes and functionality for implementing them

class snakeoil.containers.InvertedContains[source]

Bases: set

Set that inverts all contains lookup results.

Essentially, it’s a set class usable for blacklist containment testing.

>>> from snakeoil.containers import InvertedContains
>>> inverted = InvertedContains(range(10))
>>> assert 1 not in inverted
>>> assert 11 in inverted
>>> inverted.add(11)
>>> assert 11 not in inverted

Please note it cannot be iterated over due to the essentially infinite series it represents.

class snakeoil.containers.LimitedChangeSet(initial_keys, unchangable_keys=None, key_validator=None)[source]

Bases: SetMixin

Set used to limit the number of times a key can be removed/added.

specifically deleting/adding a key only once per commit, optionally blocking changes to certain keys.

>>> from snakeoil.containers import LimitedChangeSet
>>> myset = LimitedChangeSet((1, 2), unchangable_keys=(1,))
>>> assert 1 in myset
>>> myset.add(1)
>>> myset.remove(1) 
Traceback (most recent call last):
Unchangable: key '1' is unchangable
>>> myset.remove(2) # remove it, so we can try adding it
>>> assert 2 not in myset
>>> myset.add(2) 
Traceback (most recent call last):
Unchangable: key '2' is unchangable
add(key)[source]

Add an element to a set.

This has no effect if the element is already present.

changes_count()[source]
commit()[source]
remove(key)[source]

Remove an element from a set; it must be a member.

If the element is not a member, raise a KeyError.

rollback(point=0)[source]
class snakeoil.containers.ProtectedSet(orig_set)[source]

Bases: SetMixin

Wraps a set pushing all changes into a secondary set.

>>> from snakeoil.containers import ProtectedSet
>>> myset = set(range(3))
>>> protected = ProtectedSet(myset)
>>> protected.add(4)
>>> assert 4 not in myset
>>> assert 4 in protected
>>> assert 2 in protected
>>> myset.remove(2)
>>> assert 2 not in protected
add(key)[source]
class snakeoil.containers.RefCountingSet(iterable=None)[source]

Bases: dict

Set implementation that implements refcounting for add/remove, removing the key only when its refcount is 0.

This is particularly useful for essentially summing sequences that are a stream of additions/removals

>>> from snakeoil.containers import RefCountingSet
>>> myset = RefCountingSet()
>>> myset.add(1)
>>> myset.add(1)
>>> assert list(myset) == [1]
>>> myset.remove(1)
>>> assert list(myset) == [1]
>>> myset.remove(1)
>>> assert list(myset) == []
add(item)[source]

Add an element to a set.

This has no effect if the element is already present.

discard(item)[source]

Remove an element from a set if it is a member.

Unlike set.remove(), the discard() method does not raise an exception when an element is missing from the set.

remove(item)[source]

Remove an element from a set; it must be a member.

If the element is not a member, raise a KeyError.

update(items)[source]

Update a set with the union of itself and others.

class snakeoil.containers.SetMixin[source]

Bases: object

Base class for implementing set classes

Subclasses must provide __init__, __iter__ and __contains__.

Note that this is a stripped down base; it primarily implements the core math protocols, methods like symmetric_difference aren’t defined here.

exception snakeoil.containers.Unchangable(key)[source]

Bases: Exception