Package: addict-tracking-changes
addict-tracking-changesIntroductionHEADS UPBefore using the library carefully read the Known bugs and Caveats section below.Originally, this repository was a fork ofaddictby Mats Julian Olsen.
Overtime, it has substatially diverged in functionality and codebase that it made
sense to breakout as its own repository.The original addict:  provides an alternative and succient interface to manipulate a dictionary. This is especially
useful when dealing with heavily nested dictionaries. As example (taken fromhttps://github.com/mewwts/addict)
a dictionary created using standard python dictionary interface looks as follows:body={'query':{'filtered':{'query':{'match':{'description':'addictive'}},'filter':{'term':{'created_by':'Mats'}}}}}`can be summarized to following three lines:body=Dict()body.query.filtered.query.match.description='addictive'body.query.filtered.filter.term.created_by='Mats'This repo builds on original addict and adds contraptions to track key additions in the dictionary.
This features comes in quite handy in building reactive webapps where one has to respond
to all the changes made on the browser. Addict-tracking-changes is the underpinning
data-structure inofjustpy: a python based webframework build fromjustpyThe functions relevant to tracking changed history are:get_changed_historyandclear_changed_history.
Theget_changed_historyreturns an iterator of XPath style paths like/a/b/c/e(seeDemo example).Usage and examplesInstallationThis project is not on PyPI. Its a simple package with no third party dependency.
Simply clone from github and include the source directory in your PYTHONPATH.Demo examplefromaddictimportDictbody=Dict()body.query.filtered.query.match.description='addictive'body.query.filtered.filter.term.created_by='Mats'forchanged_pathinbody.get_changed_history():#<work with changed_path>body.clear_changed_history()Behaviour when values are instances of container typesaddict works as expected when the values of keys are simple data types (such as string, int, float, etc.). However, for container types such as dict, list, tuples, etc. the behaviour is somewhat differs.dicts are treated as opaque object just like simple data typesfromaddictimportDictmydict=Dict()mydict.a.b.c={'kk':1}mydict.a.b.e={'dd':1}for_inmydict.get_changed_history():print(_)will print/a/b/c
/a/b/eand not/a/b/cc/kk
/a/b/e/ddlists
are seen as container, i.e.,get_changed_historywill report path for each element of
the listfromaddictimportDictmydict=Dict()mydict.a.b=[1,[1]]mydict.a.c=[2,[2,[3]]]get_changed_history will report following paths:/a/b/0,
/a/b/1/0,
/a/c/0,
/a/c/1/0,
/a/c/1/1/"tuple, namedtuple, sets
tuple  behave same as dict and are treated as opaque data structureKnown bugs and CaveatsOnly tracks  field additions.  Deletions and updates are not tracked.freeze doesn't guards against deletionsbuilding dict from another dict as shown in following expression wont' workcjs_cfg=Dict(other_dict,track_changes=True)instead usecjs_cfg=Dict(track_changes=True)withopen("other_dict.pickle","rb")asfh:x=pickle.load(fh)for_inoj.dictWalker(x):oj.dnew(cjs_cfg,_[0],_[1])Use TrackedList for tracking nested listfromaddict_tracking_changesimportDict,TrackedListtrackerprop=Dict(track_changes=True)trackerprop.a.b=[1,TrackedList([1],track_changes=True)]trackerprop.a.c=[2,TrackedList([2,TrackedList([3],track_changes=True)],track_changes=True)]which when asked changed history will output as follows:print(list(trackerprop.get_changed_history()))output['/a/b/0','/a/b/1/0','/a/c/0','/a/c/1/0','/a/c/1/1/0']APIsAPIDescriptionDict(*args, **kwargs)Initializes a new Dict objectto_dict(self)Converts the Dict object to a regular dictionaryfreeze(self, shouldFreeze=True)Freezes the Dict object, making it immutableunfreeze(self)Unfreezes the Dict object, making it mutable againget_changed_history(self, prefix="", path_guards=None)Returns an iterator with the changed history of keysclear_changed_history(self)Clears the changed history of the Dict objectset_tracker(self, track_changes=False)Sets or resets the change tracker for the Dict objectEndNotesDocs (in readthedocs format):https://monallabs-org.github.io/addict-tracking-changes/#introduction,https://webworks.monallabs.in/addict-tracking-changesDeveloped By: webworks.monallabs.in