Overview
Weak entry, strong value immutable registry data structure. Think of it as an immutable WeakKeyDictionary that efficiently evolves into a new copy everytime you want to make a change to it.
Motivation
Immutable data structures are great for when you need to implement some kind of “snapshot” of states for easy undo/redo, time-travelling functionality. The library pyrsistent is great for that, but it lacks a map-like structure in which the keys are stored as weak references.
Registtro is an implementation of that structure, which allows for proper garbage collection of the keys/entries, while still allowing to store their states in a centralized, immutable structure.
Example
Simple implementation of an undoable store that keeps track of states for entries.
>>> from registtro import Registry
>>> class Store(object):
... """Keeps track of the history of states for entries."""
... def __init__(self):
... self._done = [Registry()]
... self._undone = []
... def init(self, entry, state):
... self._done.append(self._done[-1].update({entry: state}))
... del self._done[:-1]
... del self._undone[:]
... def get_state(self, entry):
... return self._done[-1].query(entry)
... def set_state(self, entry, state):
... del self._undone[:]
... self._done.append(self._done[-1].update({entry: state}))
... def undo(self):
... assert len(self._done) > 1, "can't undo"
... self._undone.append(self._done.pop())
... def redo(self):
... assert self._undone, "can't redo"
... self._done.append(self._undone.pop())
...
>>> class Entry(object):
... """Reads/sets state in a store."""
... def __init__(self, store, state):
... self._store = store
... store.init(self, state)
... def get_state(self):
... return self._store.get_state(self)
... def set_state(self, state):
... self._store.set_state(self, state)
...
>>> # Initialize entries.
>>> global_store = Store()
>>> entry_a = Entry(global_store, "foo")
>>> entry_b = Entry(global_store, "bar")
>>> (entry_a.get_state(), entry_b.get_state())
('foo', 'bar')
>>> # Modify entries.
>>> entry_a.set_state("FOO")
>>> entry_b.set_state("BAR")
>>> (entry_a.get_state(), entry_b.get_state())
('FOO', 'BAR')
>>> # Undo modifications.
>>> global_store.undo()
>>> (entry_a.get_state(), entry_b.get_state())
('FOO', 'bar')
>>> global_store.undo()
>>> (entry_a.get_state(), entry_b.get_state())
('foo', 'bar')
>>> # Redo modifications.
>>> global_store.redo()
>>> (entry_a.get_state(), entry_b.get_state())
('FOO', 'bar')
>>> global_store.redo()
>>> (entry_a.get_state(), entry_b.get_state())
('FOO', 'BAR')
Release files for registtro 1.4.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| registtro-1.4.0.tar.gz | 14.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| registtro-1.4.0-py2.py3-none-any.whl | Python 2, Python 3 | none | any | Details |
Total release size: 20.6 kB
Release files / registtro-1.4.0.tar.gz
| Download URL | registtro-1.4.0.tar.gz |
|---|---|
| Size | 14.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7c3996a10b8379717fd5a18f73515b89eef883b9ae70e10d457bfe0a192873f5
|
|
BLAKE2b-256 checksum How to use checksums |
9e86968a9405aa97136dcbf28c1cc789fad069166b530556cfb49a2691dcdf34
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/4.0.2 CPython/3.11.3
|
Release files / registtro-1.4.0-py2.py3-none-any.whl
| Download URL | registtro-1.4.0-py2.py3-none-any.whl |
|---|---|
| Size | 6.5 kB |
| Tags | Python 2 Python 3 |
|
SHA-256 checksum How to use checksums |
3c7986f2b2b92458914808430a8e9b49f9cffe964a56a0fcb875852fbd437e58
|
|
BLAKE2b-256 checksum How to use checksums |
b162badbb2dd2c87c64d4768a360c120e1686db9b40218cbcd27d8a57d98acab
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/4.0.2 CPython/3.11.3
|