zodict
======

Ordered dictionary which implements the corresponding
``zope.interface.common.mapping`` interface.
::

    >>> from zope.interface.common.mapping import IFullMapping
    >>> from zodict import zodict
    >>> zod = zodict()
    >>> IFullMapping.providedBy(zod)
    True

Node
====

This is a ``zodict`` which 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 ...>

The ``filtereditems`` function.
::

    >>> 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'>: child2

Move 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'>: child2

Merge 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'>: e

Changes
=======

Version 1.7.0
-------------

  -Add ``Node.detach`` function. Needed for node or subtree moving. This is
   done due to performance reasons.
   rnix, 2009-12-18

  -``Node.index`` returns now a ``NodeIndex`` object, which implements
   ``zope.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 of ``Node._index`` to int. ``uuid.UUID.__hash__``
   function was called too often
   jensens, rnix, 2009-12-18

  -make ``Node`` thread safe.
   jensens, rnix, 2009-12-18

Version 1.6.1
-------------

  -make ``Node`` trees merge properly.
   rnix, 2009-12-15

  -make getter and setter functions of ``uuid`` property private.
   rnix, 2009-12-15

Version 1.6.0
-------------

  -remove the ``traverser`` module.
   rnix, 2009-11-28

  -improve ``insertbefore`` and ``insertafter`` a little bit.
   rnix, 2009-11-28

  -add ``index`` Attribute to ``Node``. Allows access to the internal 
   ``_index`` attribute.
   rnix, 2009-11-28
  
  -remove ``@accept`` and ``@return`` decorators. Just overhead.
   rnix, 2009-11-28

Version 1.5.0
-------------
 
  -add ``insertbefore`` and ``insertafter`` function to ``Node``.
   rnix, 2009-11-27
  
  -fix ``printtree`` if ``Node.__name__`` is ``None``.
   rnix, 2009-11-20

  -add ``printtree`` debug helper function to ``Node``.
   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
   if ``interlude`` wasnt installed.
   jensens, 2009-07-16

Version 1.4.0
-------------

  -Don't allow classes as values of a ``Node``. Attribute ``__name__``
   conflicts.
   jensens, 2009-05-06 

  -``repr(nodeobj)`` now returns the real classname and not fixed
   ``<Node object`` this helps a lot while testing and using classes inheriting
   from ``Node``!
   jensens, 2009-05-06 

  -Make tests run with ``python setup.py test``.
   Removed superflous dependency on ``zope.testing``.
   jensens, 2009-05-06 

Version 1.3.3
-------------

  -Fix ``ITraverser`` interface import including BBB.

Version 1.3.2
-------------

  -Add ``root`` property to ``Node``.
   thet, 2009-04-24

Version 1.3.1
-------------

  -Add ``__delitem__`` function to ``Node``.
   rnix, 2009-04-16

Version 1.3
-----------

  -Add ``uuid`` Attribute and ``node`` function to ``Node``.
   rnix, 2009-03-23

Version 1.2
-----------

  -Add ``filtereditems`` function to ``Node``.
   rnix, 2009-03-22

Version 1.1
-----------

  -Add ``INode`` interface and implementation.
   rnix, 2009-03-18

Credits
=======

  -Written by Robert Niederreiter <rnix@squarewave.at>
   2009-03-17