{"id":24973309,"url":"https://github.com/bluedynamics/zodict","last_synced_at":"2025-03-29T06:13:00.531Z","repository":{"id":137553687,"uuid":"841364","full_name":"bluedynamics/zodict","owner":"bluedynamics","description":"zope.interface compliant ordered dictionary and zope.location aware node.","archived":false,"fork":false,"pushed_at":"2011-05-09T10:09:33.000Z","size":899,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-03T18:38:37.285Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://pypi.python.org/pypi/zodict","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bluedynamics.png","metadata":{"files":{"readme":"README.rst","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.rst","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2010-08-16T15:43:58.000Z","updated_at":"2020-01-30T17:29:15.000Z","dependencies_parsed_at":"2023-03-11T02:51:49.024Z","dependency_job_id":null,"html_url":"https://github.com/bluedynamics/zodict","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bluedynamics%2Fzodict","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bluedynamics%2Fzodict/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bluedynamics%2Fzodict/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bluedynamics%2Fzodict/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bluedynamics","download_url":"https://codeload.github.com/bluedynamics/zodict/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246145089,"owners_count":20730495,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-02-03T18:27:10.329Z","updated_at":"2025-03-29T06:13:00.509Z","avatar_url":"https://github.com/bluedynamics.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":".. contents:: **Table of Contents**\n\nRequires\n========\n\n- Python2.4+\n\nUsage\n=====\n\nZodict\n------\n\nOrdered dictionary which implements the corresponding\n``zope.interface.common.mapping`` interface.\n::\n\n    \u003e\u003e\u003e from zope.interface.common.mapping import IFullMapping\n    \u003e\u003e\u003e from zodict import Zodict\n    \u003e\u003e\u003e zod = Zodict()\n    \u003e\u003e\u003e IFullMapping.providedBy(zod)\n    True\n\nOverview\n--------\n\nXXX: copy from agx.doc, extend, formulate\n\nA node is the root of a nodespace.\n\nEvery node has a child nodespace managed by IFullMapping\n\nAttributedNodes have an addition attrs nodespace\n\nA nodespace consists of a node and its children. Every child is the root of\nits own nodespace, a subspace of the full tree.\n\nCompositions make up their child nodespace from multiple other nodespaces.\n\n\n#    \u003e\u003e\u003e nodespace(Node)['children']\n#    \u003e\u003e\u003e nodespace(Node)['attrs']\n#    \u003e\u003e\u003e nodespace(Node)['whatever']\n\n\n\n\nNode\n----\n\nThis is a ``zodict`` which provides a location. Location the zope way means\neach item in the node-tree knows its parent and its own name.\n::\n\n    \u003e\u003e\u003e from zope.location.interface import ILocation\n    \u003e\u003e\u003e from zodict import Node\n    \u003e\u003e\u003e root = Node('root')\n    \u003e\u003e\u003e ILocation.providedBy(Node)\n    True\n\n    \u003e\u003e\u003e root['child'] = Node()\n    \u003e\u003e\u003e root['child'].path\n    ['root', 'child']\n\n    \u003e\u003e\u003e child = root['child']\n    \u003e\u003e\u003e child.__name__\n    'child'\n\n    \u003e\u003e\u003e child.__parent__\n    \u003cNode object 'root' at ...\u003e\n\nThe ``filtereditems`` function.\n::\n\n    \u003e\u003e\u003e from zope.interface import Interface\n    \u003e\u003e\u003e from zope.interface import alsoProvides\n    \u003e\u003e\u003e class IMarker(Interface): pass\n    \u003e\u003e\u003e alsoProvides(root['child']['subchild'], IMarker)\n    \u003e\u003e\u003e IMarker.providedBy(root['child']['subchild'])\n    True\n\n    \u003e\u003e\u003e for item in root['child'].filtereditems(IMarker):\n    ...     print item.path\n    ['root', 'child', 'subchild']\n\nUUID related operations on Node.\n::\n\n    \u003e\u003e\u003e uuid = root['child']['subchild'].uuid\n    \u003e\u003e\u003e uuid\n    UUID('...')\n\n    \u003e\u003e\u003e root.node(uuid).path\n    ['root', 'child', 'subchild']\n\n    \u003e\u003e\u003e root.uuid = uuid\n    Traceback (most recent call last):\n      ...\n    ValueError: Given uuid was already used for another Node\n\n    \u003e\u003e\u003e import uuid\n    \u003e\u003e\u003e newuuid = uuid.uuid4()\n\n    \u003e\u003e\u003e root.uuid = newuuid\n    \u003e\u003e\u003e root['child'].node(newuuid).path\n    ['root']\n\nNode insertion (an insertafter function exist as well).\n::\n\n    \u003e\u003e\u003e root['child1'] = Node()\n    \u003e\u003e\u003e root['child2'] = Node()\n\n    \u003e\u003e\u003e node = Node('child3')\n    \u003e\u003e\u003e root.insertbefore(node, root['child2'])\n    \u003e\u003e\u003e root.printtree()\n    \u003cclass 'zodict.node.Node'\u003e: root\n      \u003cclass 'zodict.node.Node'\u003e: child1\n      \u003cclass 'zodict.node.Node'\u003e: child3\n      \u003cclass 'zodict.node.Node'\u003e: child2\n\nMove a node. Therefor we first need to detach the node we want to move from\ntree. Then insert the detached node elsewhere. In general, you can insert the\ndetached node or subtree to a complete different tree.\n::\n\n    \u003e\u003e\u003e len(root._index.keys())\n    6\n\n    \u003e\u003e\u003e node = root.detach('child4')\n    \u003e\u003e\u003e node\n    \u003cNode object 'child4' at ...\u003e\n\n    \u003e\u003e\u003e len(node._index.keys())\n    1\n    \u003e\u003e\u003e len(root._index.keys())\n    5\n\n    \u003e\u003e\u003e len(root.values())\n    4\n\n    \u003e\u003e\u003e root.insertbefore(node, root['child1'])\n    \u003e\u003e\u003e root.printtree()\n    \u003cclass 'zodict.node.Node'\u003e: root\n      \u003cclass 'zodict.node.Node'\u003e: child4\n      \u003cclass 'zodict.node.Node'\u003e: child1\n      \u003cclass 'zodict.node.Node'\u003e: child3\n      \u003cclass 'zodict.node.Node'\u003e: child5\n      \u003cclass 'zodict.node.Node'\u003e: child2\n\nMerge 2 Node Trees.\n::\n\n    \u003e\u003e\u003e tree1 = Node()\n    \u003e\u003e\u003e tree1['a'] = Node()\n    \u003e\u003e\u003e tree1['b'] = Node()\n    \u003e\u003e\u003e tree2 = Node()\n    \u003e\u003e\u003e tree2['d'] = Node()\n    \u003e\u003e\u003e tree2['e'] = Node()\n    \u003e\u003e\u003e tree1._index is tree2._index\n    False\n\n    \u003e\u003e\u003e len(tree1._index.keys())\n    3\n\n    \u003e\u003e\u003e tree1.printtree()\n    \u003cclass 'zodict.node.Node'\u003e: None\n      \u003cclass 'zodict.node.Node'\u003e: a\n      \u003cclass 'zodict.node.Node'\u003e: b\n\n    \u003e\u003e\u003e len(tree2._index.keys())\n    3\n\n    \u003e\u003e\u003e tree2.printtree()\n    \u003cclass 'zodict.node.Node'\u003e: None\n      \u003cclass 'zodict.node.Node'\u003e: d\n      \u003cclass 'zodict.node.Node'\u003e: e\n\n    \u003e\u003e\u003e tree1['c'] = tree2\n    \u003e\u003e\u003e len(tree1._index.keys())\n    6\n\n    \u003e\u003e sorted(tree1._index.values(), key=lambda x: x.__name__)\n\n    \u003e\u003e\u003e tree1._index is tree2._index\n    True\n\n    \u003e\u003e\u003e tree1.printtree()\n    \u003cclass 'zodict.node.Node'\u003e: None\n      \u003cclass 'zodict.node.Node'\u003e: a\n      \u003cclass 'zodict.node.Node'\u003e: b\n      \u003cclass 'zodict.node.Node'\u003e: c\n        \u003cclass 'zodict.node.Node'\u003e: d\n        \u003cclass 'zodict.node.Node'\u003e: e\n\nLifecycleNode\n-------------\n\nThe ``LifecycleNode`` is able to send out notifies with object-events based on\n``zope.lifecycleevent`` subclasses.\n\nCreation of Node\n    ``zodict.events.NodeCreatedEvent`` implementing\n    ``zodict.interfaces.INodeCreatedEvent``.\n\nAdding childs to Node\n    ``zodict.events.NodeAddedEvent`` implementing\n    ``zodict.interfaces.INodeAddedEvent``.\n\nDeleting childs from Node\n    ``zodict.events.NodeRemovedEvent`` implementing\n    ``zodict.interfaces.INodeRemovedEvent``.\n\nDetaching childs from Node\n    ``zodict.events.NodeDetachedEvent`` implementing\n    ``zodict.interfaces.INodeDetachedEvent``.\n\nIn subclasses of Node the event classes can be exchanged by modifying the\nclass attribute ``events`` on the node. It is a dictionary with the keys:\n``['created', 'added', 'removed', 'detached']``\n\nThread safe Locking of a Tree\n-----------------------------\n\nNot ``Node`` nor ``LifecycleNode`` are thread safe. Application-builder are\nresponsible for this. Major reason: Acquiring and releasing locks is an\nexpensive operation.\n\nThe module ``zodict.locking`` provides a mechanism to lock the whole tree\nthread safe. A class and a decorator is provided. The class is intended to be\nused standalone with some Node, the decorator to be used on subclasses of\n``Node`` or ``LifecycleNode``.\n\n``zodict.locking.TreeLock`` is a adapter like class on a Node. It can be used\nin Python \u003e 2.6 within the ``with`` statement.\n::\n\n    \u003e\u003e\u003e node = Node()\n    \u003e\u003e\u003e with TreeLock(node):\n    \u003e\u003e\u003e     # do something on the locked tree\n    \u003e\u003e\u003e     node['foo'] = Node()\n\nAlternative it can be used in older Python version with in a try: finally.\n::\n\n    \u003e\u003e\u003e from zodict.locking import TreeLock\n    \u003e\u003e\u003e lock = TreeLock(node)\n    \u003e\u003e\u003e lock.acquire()\n    \u003e\u003e\u003e try:\n    \u003e\u003e\u003e     # do something on the locked tree\n    \u003e\u003e\u003e     node['bar'] = Node()\n    \u003e\u003e\u003e finally:\n    \u003e\u003e\u003e     lock.release()\n\n``zodict.locking.locktree`` Decorator for methods of a (sub-)class of ``Node``.\n::\n\n    \u003e\u003e\u003e from zodict.locking import locktree\n    \u003e\u003e\u003e class LockedNode(Node):\n    ...\n    ...     @locktree\n    ...     def __setitem__(self, key, val):\n    ...         super(LockedNode, self).__setitem__(key, val)\n\nContributors\n============\n\n- Robert Niederreiter \u003crnix@squarewave.at\u003e\n\n- Jens Klein \u003cjens@bluedynamics.com\u003e\n\nChanges\n=======\n\nVersion 1.9.4dev\n----------------\n\n- Node provides now ``get`` method (promised by IFullMapping) again.\n  [jensens, 2010-09-04]\n\nVersion 1.9.3\n-------------\n\n- Provide abstract ``_Node`` implementation.\n  [rnix, 2010-07-08]\n\n- Typos in documentation.\n  [thet, 2010-07-06]\n\n- BBB imports in except block rather than trying it first.\n  [thet, 2010-07-06]\n\n- Buildout configuration for testing purposes.\n  [thet, 2010-07-06]\n\nVersion 1.9.2\n-------------\n\n- set ``child.__name__`` and ``child.__parent__`` before ``child.keys()`` call\n  for index check in ``Node.__setitem__``. ``keys()`` of child might depend\n  on those.\n  [rnix, 2010-05-01]\n\n- Separated ``AttributedNode`` from ``LifecycleNode``, so attributes can be used\n  without events now.\n  [jensens, 2010-04-28]\n\nVersion 1.9.1\n-------------\n\n- Add test for bool evaluation\n  [rnix, 2010-04-21]\n\n- Add ``__setattr__`` and ``__getattr__`` to ``NodeAttributes`` object.\n  [rnix, 2010-04-21]\n\n- BBB compatibility for zope2.9\n  [rnix, jensens, 2010-02-17]\n\nVersion 1.9.0\n-------------\n\n- Make zodict compatible with python 2.4 again, BBB\n  [jensens, 2009-12-23]\n\n- Add locking test\n  [rnix, 2009-12-23]\n\n- Refactor locking, remove tree-locking from Node base implementations.\n  Add easy to use locking class and a decorator intended to be used in\n  applications and subclasses of ``Node``.\n  [jensens, 2009-12-23]\n\n- Introduce ``ICallableNode``, ``ILeaf`` and ``IRoot`` interfaces.\n  [rnix, 2009-12-23]\n\n- Change Lisence to PSF\n  [rnix, 2009-12-22]\n\n- Add ``zodict.node.NodeAttributes`` object.\n  [rnix, 2009-12-22]\n\n- Add ``attributes`` Attribute to ``LifecycleNode``.\n  [rnix, 2009-12-22]\n\n- Add ``ILifecycleNode`` and ``INodeAttributes`` interfaces.\n  [rnix, 2009-12-22]\n\n- Removed typo in private variable name. added notify-suppress to setitem of\n  ``LifecycleNode``.\n  [jensens, 2009-12-22]\n\nVersion 1.8.0\n-------------\n\n- Added ``zope.lifecycle`` events to the new ``LifecycleNode``. You can\n  easiely override them with your own events.\n  [jensens, 2009-12-21]\n\n- Renamed class ``zodict`` to ``Zodict``, renamed module ``zodict.zodict`` to\n  ``zodict._zodict``. This avoids ugly clashes on import (package vs. module\n  vs.class). BBB import is provided in the 1.x release series.\n  [jensens, 2009-12-21]\n\nVersion 1.7.0\n-------------\n\n- Add ``Node.detach`` function. Needed for node or subtree moving. This is\n  done due to performance reasons.\n  [rnix, 2009-12-18]\n\n- ``Node.index`` returns now a ``NodeIndex`` object, which implements\n  ``zope.interface.common.mapping.IReadMapping``. This functions convert uuid\n  instances to integers before node lookup. So we still fit the contract of\n  returning nodes from index by uuid.\n  [rnix, 2009-12-18]\n\n- Change type of keys of ``Node._index`` to int. ``uuid.UUID.__hash__``\n  function was called too often\n  [jensens, rnix, 2009-12-18]\n\n- make ``Node`` thread safe.\n  [jensens, rnix, 2009-12-18]\n\nVersion 1.6.1\n-------------\n\n- make ``Node`` trees merge properly.\n  [rnix, 2009-12-15]\n\n- make getter and setter functions of ``uuid`` property private.\n  [rnix, 2009-12-15]\n\nVersion 1.6.0\n-------------\n\n- remove the ``traverser`` module.\n  [rnix, 2009-11-28]\n\n- improve ``insertbefore`` and ``insertafter`` a little bit.\n  [rnix, 2009-11-28]\n\n- add ``index`` Attribute to ``Node``. Allows access to the internal\n  ``_index`` attribute.\n  [rnix, 2009-11-28]\n\n- remove ``@accept`` and ``@return`` decorators. Just overhead.\n  [rnix, 2009-11-28]\n\nVersion 1.5.0\n-------------\n\n- add ``insertbefore`` and ``insertafter`` function to ``Node``.\n  [rnix, 2009-11-27]\n\n- fix ``printtree`` if ``Node.__name__`` is ``None``.\n  [rnix, 2009-11-20]\n\n- add ``printtree`` debug helper function to ``Node``.\n  [rnix, 2009-11-09]\n\n- define own Traverser interface and reduce dependencies.\n  [rnix, 2009-10-28]\n\n- removed import of tests from zodicts ``__init__``. this caused import errors\n  if ``interlude`` wasnt installed.\n  [jensens, 2009-07-16]\n\nVersion 1.4.0\n-------------\n\n- Don't allow classes as values of a ``Node``. Attribute ``__name__``\n  conflicts.\n  [jensens, 2009-05-06]\n\n- ``repr(nodeobj)`` now returns the real classname and not fixed\n  ``\u003cNode object`` this helps a lot while testing and using classes inheriting\n  from ``Node``!\n  [jensens, 2009-05-06]\n\n- Make tests run with ``python setup.py test``.\n  Removed superflous dependency on ``zope.testing``.\n  [jensens, 2009-05-06]\n\nVersion 1.3.3\n-------------\n\n- Fix ``ITraverser`` interface import including BBB.\n\nVersion 1.3.2\n-------------\n\n- Add ``root`` property to ``Node``.\n  [thet, 2009-04-24]\n\nVersion 1.3.1\n-------------\n\n- Add ``__delitem__`` function to ``Node``.\n  [rnix, 2009-04-16]\n\nVersion 1.3\n-----------\n\n- Add ``uuid`` Attribute and ``node`` function to ``Node``.\n  [rnix, 2009-03-23]\n\nVersion 1.2\n-----------\n\n- Add ``filtereditems`` function to ``Node``.\n  [rnix, 2009-03-22]\n\nVersion 1.1\n-----------\n\n- Add ``INode`` interface and implementation.\n  [rnix, 2009-03-18]\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbluedynamics%2Fzodict","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbluedynamics%2Fzodict","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbluedynamics%2Fzodict/lists"}