GitXplorerGitXplorer
j

jundo

public
13 stars
0 forks
1 issues

Commits

List of commits on branch master.
Unverified
16e806cef60a2bd88d3916bff61d2befc3db5956

add GHA badge

jjustvanrossum committed 3 years ago
Unverified
a2e473a4ef2c54e7191f7f145fa18ab8da73cc4c

take long description from README.md

jjustvanrossum committed 3 years ago
Unverified
ebdf721c3cdf70956ff5d9dc9d634aa7cfd01ea0

add deply stage

jjustvanrossum committed 3 years ago
Unverified
21b62d09427e50fe1228ba44149f91149096fc08

use setuptools_scm

jjustvanrossum committed 3 years ago
Unverified
41fd2719ce9419da8237398a9bd0507b1cf1429e

install as editable, to make pytest happy

jjustvanrossum committed 3 years ago
Unverified
5de1194e7c6a6ef146b697dcf5e7aecc7cb09978

remove main doctest prog

jjustvanrossum committed 3 years ago

README

The README file for this repository.

Build, Test & Deploy

jundo

A general purpose library to help implement undo for existing objects.

The main idea is that if one limits oneself to objects that can be viewed as JSON-like data structures (ie. are composed of strings, numbers, lists and dictionaries) it is possible to record changes in a completely generic way, and use these recordings to reconstruct objects or to roll back changes, for example to implement undo.

A key requirement was that the model objects must be completely decoupled from the recording mechanism, and will not need any awareness of it.

The way this is implemented here is through proxy objects: instead of modifying the original model objects directly, one uses proxy objects that mimic the model object, allowing the proxy to pass on change information (deltas) to an undo manager.

The undo manager collects change deltas (and their inverses), and can apply them to the original model object when undo or redo is requested.

The model object is passed to the undo manager with the undoManager.setModel(model), which returns a proxy for the model. Client code must use the proxy object instead of the model to modify the model. Here is an example:

>>> model = [1, 2, 3, {"a": 123}]
>>> um = UndoManager()
>>> proxy = um.setModel(model)
>>> # Modifications must be done within a change set context:
>>> with um.changeSet(title="replace list item"):
...     proxy[1] = 2000
...
>>> model[1]
2000
>>> um.undo()
>>> model[1]
2
>>> um.redo()
>>> model[1]
2000
>>> with um.changeSet(title="replace nested dict item"):
...     proxy[3]["a"] = 456
...
>>> model[3]["a"]
456
>>> um.undo()
>>> model[3]["a"]
123

In this example, only Python list and dict objects are used as containers, but any type of Mapping or Sequence (in the collections.abc-sense) can be used, or any object type that uses attribute access to modify its model data. See the Examples folder for more elaborate examples.

Sets are also supported.

To support model objects that are not JSON-like, custom proxy classes can be registered via the registerUndoProxy() function.

Acknowledgments

The approach implemented here is inspired by Raph Levien's ideas, as he wrote them down here. It also draws inspiration from jsonpatch.