Package: zodict
Table of ContentsRequiresUsageZodictNodeLifecycleNodeThread safe Locking of a TreeChangesVersion 1.9.3Version 1.9.2Version 1.9.1Version 1.9.0Version 1.8.0Version 1.7.0Version 1.6.1Version 1.6.0Version 1.5.0Version 1.4.0Version 1.3.3Version 1.3.2Version 1.3.1Version 1.3Version 1.2Version 1.1CreditsRequiresPython2.4+UsageZodictOrdered dictionary which implements the correspondingzope.interface.common.mappinginterface.>>> from zope.interface.common.mapping import IFullMapping
>>> from zodict import Zodict
>>> zod = Zodict()
>>> IFullMapping.providedBy(zod)
TrueNodeThis is azodictwhich provides a location. Location the zope way means
each item in the node-tree knows its parent and its own name.>>> from zope.location.interface import ILocation
>>> from zodict import Node
>>> root = Node('root')
>>> ILocation.providedBy(Node)
True

>>> root['child'] = Node()
>>> root['child'].path
['root', 'child']

>>> child = root['child']
>>> child.__name__
'child'

>>> child.__parent__
<Node object 'root' at ...>Thefiltereditemsfunction.>>> from zope.interface import Interface
>>> from zope.interface import alsoProvides
>>> class IMarker(Interface): pass
>>> alsoProvides(root['child']['subchild'], IMarker)
>>> IMarker.providedBy(root['child']['subchild'])
True

>>> for item in root['child'].filtereditems(IMarker):
...     print item.path
['root', 'child', 'subchild']UUID related operations on Node.>>> uuid = root['child']['subchild'].uuid
>>> uuid
UUID('...')

>>> root.node(uuid).path
['root', 'child', 'subchild']

>>> root.uuid = uuid
Traceback (most recent call last):
  ...
ValueError: Given uuid was already used for another Node

>>> import uuid
>>> newuuid = uuid.uuid4()

>>> root.uuid = newuuid
>>> root['child'].node(newuuid).path
['root']Node insertion (an insertafter function exist as well).>>> root['child1'] = Node()
>>> root['child2'] = Node()

>>> node = Node('child3')
>>> root.insertbefore(node, root['child2'])
>>> root.printtree()
<class 'zodict.node.Node'>: root
  <class 'zodict.node.Node'>: child1
  <class 'zodict.node.Node'>: child3
  <class 'zodict.node.Node'>: child2Move a node. Therefor we first need to detach the node we want to move from
tree. Then insert the detached node elsewhere. In general, you can insert the
detached node or subtree to a complete different tree.>>> len(root._index.keys())
6

>>> node = root.detach('child4')
>>> node
<Node object 'child4' at ...>

>>> len(node._index.keys())
1
>>> len(root._index.keys())
5

>>> len(root.values())
4

>>> root.insertbefore(node, root['child1'])
>>> root.printtree()
<class 'zodict.node.Node'>: root
  <class 'zodict.node.Node'>: child4
  <class 'zodict.node.Node'>: child1
  <class 'zodict.node.Node'>: child3
  <class 'zodict.node.Node'>: child5
  <class 'zodict.node.Node'>: child2Merge 2 Node Trees.>>> tree1 = Node()
>>> tree1['a'] = Node()
>>> tree1['b'] = Node()
>>> tree2 = Node()
>>> tree2['d'] = Node()
>>> tree2['e'] = Node()
>>> tree1._index is tree2._index
False

>>> len(tree1._index.keys())
3

>>> tree1.printtree()
<class 'zodict.node.Node'>: None
  <class 'zodict.node.Node'>: a
  <class 'zodict.node.Node'>: b

>>> len(tree2._index.keys())
3

>>> tree2.printtree()
<class 'zodict.node.Node'>: None
  <class 'zodict.node.Node'>: d
  <class 'zodict.node.Node'>: e

>>> tree1['c'] = tree2
>>> len(tree1._index.keys())
6

>> sorted(tree1._index.values(), key=lambda x: x.__name__)

>>> tree1._index is tree2._index
True

>>> tree1.printtree()
<class 'zodict.node.Node'>: None
  <class 'zodict.node.Node'>: a
  <class 'zodict.node.Node'>: b
  <class 'zodict.node.Node'>: c
    <class 'zodict.node.Node'>: d
    <class 'zodict.node.Node'>: eLifecycleNodeTheLifecycleNodeis able to send out notifies with object-events based onzope.lifecycleeventsubclasses.Creation of Nodezodict.events.NodeCreatedEventimplementingzodict.interfaces.INodeCreatedEvent.Adding childs to Nodezodict.events.NodeAddedEventimplementingzodict.interfaces.INodeAddedEvent.Deleting childs from Nodezodict.events.NodeRemovedEventimplementingzodict.interfaces.INodeRemovedEvent.Detaching childs from Nodezodict.events.NodeDetachedEventimplementingzodict.interfaces.INodeDetachedEvent.In subclasses of Node the event classes can be exchanged by modifying the
class attributeeventson the node. It is a dictionary with the keys:['created', 'added', 'removed', 'detached']Thread safe Locking of a TreeNotNodenorLifecycleNodeare thread safe. Application-builder are
responsible for this. Major reason: Acquiring and releasing locks is an
expensive operation.The modulezodict.lockingprovides a mechanism to lock the whole tree
thread safe. A class and a decorator is provided. The class is intended to be
used standalone with some Node, the decorator to be used on subclasses ofNodeorLifecycleNode.zodict.locking.TreeLockis a adapter like class on a Node. It can be used
in Python > 2.6 within thewithstatement.>>> node = Node()
>>> with TreeLock(node):
>>>     # do something on the locked tree
>>>     node['foo'] = Node()Alternative it can be used in older Python version with in a try: finally.>>> from zodict.locking import TreeLock
>>> lock = TreeLock(node)
>>> lock.acquire()
>>> try:
>>>     # do something on the locked tree
>>>     node['bar'] = Node()
>>> finally:
>>>     lock.release()zodict.locking.locktreeDecorator for methods of a (sub-)class ofNode.>>> from zodict.locking import locktree
>>> class LockedNode(Node):
...
...     @locktree
...     def __setitem__(self, key, val):
...         super(LockedNode, self).__setitem__(key, val)ChangesVersion 1.9.3Provide abstract_Nodeimplementation.
[rnix, 2010-07-08]Typos in documentation.
[thet, 2010-07-06]BBB imports in except block rather than trying it first.
[thet, 2010-07-06]Buildout configuration for testing purposes.
[thet, 2010-07-06]Version 1.9.2setchild.__name__andchild.__parent__beforechild.keys()call
for index check inNode.__setitem__.keys()of child might depend
on those.
[rnix, 2010-05-01]SeparatedAttributedNodefromLifecycleNode, so attributes can be used
without events now.
[jensens, 2010-04-28]Version 1.9.1Add test for bool evaluation
[rnix, 2010-04-21]Add__setattr__and__getattr__toNodeAttributesobject.
[rnix, 2010-04-21]BBB compatibility for zope2.9
[rnix, jensens, 2010-02-17]Version 1.9.0Make zodict compatible with python 2.4 again, BBB
[jensens, 2009-12-23]Add locking test
[rnix, 2009-12-23]Refactor locking, remove tree-locking from Node base implementations.
Add easy to use locking class and a decorator intended to be used in
applications and subclasses ofNode.
[jensens, 2009-12-23]IntroduceICallableNode,ILeafandIRootinterfaces.
[rnix, 2009-12-23]Change Lisence to PSF
[rnix, 2009-12-22]Addzodict.node.NodeAttributesobject.
[rnix, 2009-12-22]AddattributesAttribute toLifecycleNode.
[rnix, 2009-12-22]AddILifecycleNodeandINodeAttributesinterfaces.
[rnix, 2009-12-22]Removed typo in private variable name. added notify-suppress to setitem ofLifecycleNode.
[jensens, 2009-12-22]Version 1.8.0Addedzope.lifecycleevents to the newLifecycleNode. You can
easiely override them with your own events.
[jensens, 2009-12-21]Renamed classzodicttoZodict, renamed modulezodict.zodicttozodict._zodict. This avoids ugly clashes on import (package vs. module
vs.class). BBB import is provided in the 1.x release series.
[jensens, 2009-12-21]Version 1.7.0AddNode.detachfunction. Needed for node or subtree moving. This is
done due to performance reasons.
[rnix, 2009-12-18]Node.indexreturns now aNodeIndexobject, which implementszope.interface.common.mapping.IReadMapping. This functions convert uuid
instances to integers before node lookup. So we still fit the contract of
returning nodes from index by uuid.
[rnix, 2009-12-18]Change type of keys ofNode._indexto int.uuid.UUID.__hash__function was called too often
[jensens, rnix, 2009-12-18]makeNodethread safe.
[jensens, rnix, 2009-12-18]Version 1.6.1makeNodetrees merge properly.
[rnix, 2009-12-15]make getter and setter functions ofuuidproperty private.
[rnix, 2009-12-15]Version 1.6.0remove thetraversermodule.
[rnix, 2009-11-28]improveinsertbeforeandinsertaftera little bit.
[rnix, 2009-11-28]addindexAttribute toNode. Allows access to the internal_indexattribute.
[rnix, 2009-11-28]remove@acceptand@returndecorators. Just overhead.
[rnix, 2009-11-28]Version 1.5.0addinsertbeforeandinsertafterfunction toNode.
[rnix, 2009-11-27]fixprinttreeifNode.__name__isNone.
[rnix, 2009-11-20]addprinttreedebug helper function toNode.
[rnix, 2009-11-09]define own Traverser interface and reduce dependencies.
[rnix, 2009-10-28]removed import of tests from zodicts__init__. this caused import errors
ifinterludewasnt installed.
[jensens, 2009-07-16]Version 1.4.0Don’t allow classes as values of aNode. Attribute__name__conflicts.
[jensens, 2009-05-06]repr(nodeobj)now returns the real classname and not fixed<Node objectthis helps a lot while testing and using classes inheriting
fromNode!
[jensens, 2009-05-06]Make tests run withpython setup.py test.
Removed superflous dependency onzope.testing.
[jensens, 2009-05-06]Version 1.3.3FixITraverserinterface import including BBB.Version 1.3.2Addrootproperty toNode.
[thet, 2009-04-24]Version 1.3.1Add__delitem__function toNode.
[rnix, 2009-04-16]Version 1.3AdduuidAttribute andnodefunction toNode.
[rnix, 2009-03-23]Version 1.2Addfiltereditemsfunction toNode.
[rnix, 2009-03-22]Version 1.1AddINodeinterface and implementation.
[rnix, 2009-03-18]CreditsWritten by Robert Niederreiter <rnix@squarewave.at>Contributions and ideas by Jens Klein <jens@bluedynamics.com>