{ "info": { "author": "Zope Corporation", "author_email": "zope3-dev@zope.org", "bugtrack_url": null, "classifiers": [], "description": "An efficient, persistent and subclassable dict\n==============================================\n\nPersistentDict is very inefficient if it contains more than a couple\nof values, and BTrees are not recommended to inherit from.\n\nThis class is a simple wrapper over a BTree. It retains the\nefficiency of BTrees and is safe to use as a base class. Also, it\nimplements the full Python dict interface.\n\n >>> from zc.dict import Dict\n >>> d = Dict()\n >>> d\n \n \n >>> d['foo'] = 'bar'\n >>> len(d)\n 1\n \n >>> d['bar'] = 'baz'\n >>> len(d)\n 2\n\nNote that an important difference between the Python dict and this Dict is\nthat the Python dict uses hashes, and this uses BTree comparisons.\nPractically, this means that your keys should be of homogenous types.\nWe use strings in these examples.\n\nLength is maintained separately, because len on a BTree is inefficient,\nas it has to wake up all buckets in the tree from the database.\n\n >>> d._len\n \n >>> d._len()\n 2\n\nIn order to keep updates efficient for small changes, we unroll them\nas a series of setitems.\n\n >>> d.update({'bar': 'moo', 'ding': 'dong', 'beep': 'beep'})\n >>> len(d)\n 4\n\nThe Dict supports the full ``update`` interface.\n\n >>> d.update([['sha', 'zam'], ['ka', 'pow']])\n >>> len(d)\n 6\n >>> d['ka']\n 'pow'\n >>> d.update(left='hook', right='jab')\n >>> len(d)\n 8\n >>> d['left']\n 'hook'\n\n``pop`` needs to update the length.\n\n >>> d.pop('sha')\n 'zam'\n >>> d.pop('ka')\n 'pow'\n >>> d.pop('left')\n 'hook'\n >>> d.pop('right')\n 'jab'\n >>> len(d)\n 4\n\n...except when it doesn't.\n\n >>> d.pop('nonexistent')\n Traceback (most recent call last):\n ...\n KeyError: 'nonexistent'\n >>> d.pop('nonexistent', 42)\n 42\n >>> len(d)\n 4\n\n``setdefault`` also sometimes needs to update the length.\n\n >>> len(d)\n 4\n >>> d.setdefault('newly created', 'value')\n 'value'\n >>> d['newly created']\n 'value'\n >>> len(d)\n 5\n\n >>> d.setdefault('newly created', 'other')\n 'value'\n >>> d['newly created']\n 'value'\n >>> len(d)\n 5\n\n >>> del d['newly created'] # set things back to the way they were...\n\n``keys``, ``values`` and ``items`` return normal Python lists. Because of\nthe underlying BTree, these are always in sort order of the keys.\n\n >>> d.keys()\n ['bar', 'beep', 'ding', 'foo']\n \n >>> d.values()\n ['moo', 'beep', 'dong', 'bar']\n \n >>> d.items()\n [('bar', 'moo'), ('beep', 'beep'), ('ding', 'dong'), ('foo', 'bar')]\n\nHowever, efficient BTree iterators are available via the iter methods:\n\n >>> iter(d)\n \n >>> d.iterkeys()\n \n \n >>> d.iteritems()\n \n \n >>> d.itervalues()\n \n\npopitem removes from the dict and returns a key-value pair:\n\n >>> len(d)\n 4\n \n >>> d.popitem()\n ('bar', 'moo')\n \n >>> len(d)\n 3\n\nThe copy method creates a copy of a Dict:\n\n >>> c = d.copy()\n >>> c.items() == d.items()\n True\n\nHowever we don't support comparison, except for identity, because of\ncowardice:\n\n >>> c == d\n False\n >>> Dict() == {}\n False\n >>> d == d\n True\n\nclear removes all the keys from the dict:\n\n >>> d.clear()\n >>> d.keys()\n []\n >>> len(d)\n 0\n\nThe rest of the dict methods are delegated to the underlying BTree:\n\n >>> c.has_key('beep')\n True\n >>> 'BEEP' in c\n False\n >>> c.get('nonexistent', 'default')\n 'default'\n\nSubclassing\n-----------\n\nFor easy subclassing, the dict is intended to have three important\ncharacteristics:\n\n- All addition is done with __setitem__ so overriding it will control\n addition.\n\n- All removal is done with either ``pop`` or ``clear`` so overriding these\n methods will control removal.\n\n- Calling __init__ without passing an argument will not try to access the\n ``update`` method.\n\nLet's demonstrate these with a quick subclass.\n\n >>> class Demo(Dict):\n ... def __setitem__(self, key, value):\n ... print '__setitem__', key, value\n ... super(Demo, self).__setitem__(key, value)\n ... def pop(self, key, *args):\n ... print 'pop', key, args and arg[0] or '---'\n ... return super(Demo, self).pop(key, *args)\n ... def update(self, *args, **kwargs):\n ... print 'update'\n ... super(Demo, self).update(*args, **kwargs)\n ... def clear(self):\n ... print 'clear'\n ... super(Demo, self).clear()\n ...\n \n >>> demo1 = Demo()\n >>> demo2 = Demo([['foo', 'bar'], ['bing', 'baz']], sha='zam')\n update\n __setitem__ foo bar\n __setitem__ bing baz\n __setitem__ sha zam\n >>> demo2.setdefault('babble')\n __setitem__ babble None\n >>> del demo2['bing']\n pop bing ---\n >>> demo2.popitem()\n pop babble ---\n ('babble', None)\n >>> demo2.clear()\n clear\n\nRegression tests\n----------------\n\nWhen setting an item that's already in the dict, the length is not\nincreased:\n\n >>> d.clear()\n >>> d['foo'] = 'bar'\n >>> d['foo'] = 'baz'\n >>> len(d)\n 1\n\n\nOrdered Dict: An persistent container that maintains order\n==========================================================\n\nAn OrderedDict provides most of the functionality of a Dict, with the\nadditional feature that it remembers the order in which items were added.\nIt also provides the API to reorder the items.\n\nImportantly, the OrderedDict currently uses a PersistentList to store\nthe order, which does not have good behavior for large collections,\nbecause the entire collection of keys must be pickled every time any\nkey, or ordering, changes. A BList would be a preferred data structure,\nbut that has not yet been released.\n\n >>> from zc.dict import OrderedDict\n >>> d = OrderedDict()\n >>> d\n \n \n >>> d['foo'] = 'bar'\n >>> len(d)\n 1\n \n >>> d['bar'] = 'baz'\n >>> len(d)\n 2\n\n >>> d['foo']\n 'bar'\n >>> d['bar']\n 'baz'\n\nThe keys are currently in the order added.\n\n >>> list(d)\n ['foo', 'bar']\n\nNote that an important difference between the Python dict and the\nOrderedDict is that the Python dict uses hashes, and this uses BTree\ncomparisons. Practically, this means that your keys should be of\nhomogenous types. We use strings in these examples.\n\nLength is maintained separately, because len on a BTree is inefficient,\nas it has to wake up all buckets in the tree from the database.\n\n >>> d._len\n \n >>> d._len()\n 2\n\nIn order to keep updates efficient for small changes, we unroll them\nas a series of setitems.\n\n >>> d.update({'bar': 'moo', 'ding': 'dong', 'beep': 'beep'})\n >>> len(d)\n 4\n\nNote that the result of an update of multiple new items in a data\nstructure without order will add the new items to the end of the ordered\ndict in an undefined order. To set our order, we need to introduce a new\nmethod: ``updateOrder``. This method is a heavy-handed approach to changing\nthe order: supply a new one.\n\n >>> list(d) == ['bar', 'beep', 'ding', 'foo']\n False\n >>> d.updateOrder(('bar', 'beep', 'ding', 'foo'))\n >>> d.keys()\n ['bar', 'beep', 'ding', 'foo']\n\n\n`updateOrder` expects the entire list of keys in the new order\n\n >>> d.updateOrder(['bar', 'beep', 'ding'])\n Traceback (most recent call last):\n ...\n ValueError: Incompatible key set.\n\n >>> d.updateOrder(['bar', 'beep', 'ding', 'sha', 'foo'])\n Traceback (most recent call last):\n ...\n ValueError: Incompatible key set.\n\n >>> d.updateOrder(['bar', 'beep', 'ding', 'sha'])\n Traceback (most recent call last):\n ...\n ValueError: Incompatible key set.\n\n >>> d.updateOrder(['bar', 'beep', 'ding', 'ding'])\n Traceback (most recent call last):\n ...\n ValueError: Duplicate keys in order.\n\nThe Dict supports the full ``update`` interface. If the input values are\nordered, the result will be as well.\n\n >>> d.update([['sha', 'zam'], ['ka', 'pow']])\n >>> len(d)\n 6\n >>> d['ka']\n 'pow'\n >>> d.keys()\n ['bar', 'beep', 'ding', 'foo', 'sha', 'ka']\n\nIf keyword arguments are used, no order to the new items is implied, but\nit otherwise works as expected.\n\n >>> d.update(left='hook', right='jab')\n >>> len(d)\n 8\n >>> d['left']\n 'hook'\n\n``pop`` needs to update the length, and maintain the order.\n\n >>> d.pop('sha')\n 'zam'\n >>> d.pop('ka')\n 'pow'\n >>> d.pop('left')\n 'hook'\n >>> d.pop('right')\n 'jab'\n >>> len(d)\n 4\n >>> d.keys()\n ['bar', 'beep', 'ding', 'foo']\n\n...except when it doesn't.\n\n >>> d.pop('nonexistent')\n Traceback (most recent call last):\n ...\n KeyError: 'nonexistent'\n >>> d.pop('nonexistent', 42)\n 42\n >>> len(d)\n 4\n\n``setdefault`` also sometimes needs to update the length.\n\n >>> len(d)\n 4\n >>> d.setdefault('newly created', 'value')\n 'value'\n >>> d['newly created']\n 'value'\n >>> len(d)\n 5\n >>> d.keys()\n ['bar', 'beep', 'ding', 'foo', 'newly created']\n\n >>> d.setdefault('newly created', 'other')\n 'value'\n >>> d['newly created']\n 'value'\n >>> len(d)\n 5\n\n >>> del d['newly created'] # set things back to the way they were...\n\n``keys``, ``values`` and ``items`` return normal Python lists. Because of\nthe underlying BTree, these are always in sort order of the keys.\n\n >>> d.keys()\n ['bar', 'beep', 'ding', 'foo']\n \n >>> d.values()\n ['moo', 'beep', 'dong', 'bar']\n \n >>> d.items()\n [('bar', 'moo'), ('beep', 'beep'), ('ding', 'dong'), ('foo', 'bar')]\n\nHowever, efficient iterators are available via the iter methods:\n\n >>> iter(d)\n \n >>> d.iterkeys()\n \n \n >>> d.iteritems()\n \n \n >>> d.itervalues()\n \n\npopitem removes an item from the dict and returns a key-value pair:\n\n >>> len(d)\n 4\n \n >>> d.popitem()\n ('bar', 'moo')\n \n >>> len(d)\n 3\n\nThe copy method creates a copy of a Dict:\n\n >>> c = d.copy()\n >>> c.items() == d.items()\n True\n\nHowever we don't support comparison, except for identity, because of\ncowardice:\n\n >>> c == d\n False\n >>> OrderedDict() == {}\n False\n >>> d == d\n True\n\nclear removes all the keys from the dict:\n\n >>> d.clear()\n >>> d.keys()\n []\n >>> len(d)\n 0\n\nThe rest of the dict methods are delegated to the underlying BTree:\n\n >>> c.has_key('beep')\n True\n >>> 'BEEP' in c\n False\n >>> c.get('nonexistent', 'default')\n 'default'\n\nSubclassing\n-----------\n\nFor easy subclassing, the ordered dict is intended to have three important\ncharacteristics:\n\n- All addition is done with __setitem__ so overriding it will control\n addition.\n\n- All removal is done with either ``pop`` or ``clear`` so overriding these\n methods will control removal.\n\n- Calling __init__ without passing an argument will not try to access the\n ``update`` method.\n\nLet's demonstrate these with a quick subclass.\n\n >>> class Demo(OrderedDict):\n ... def __setitem__(self, key, value):\n ... print '__setitem__', key, value\n ... super(Demo, self).__setitem__(key, value)\n ... def pop(self, key, *args):\n ... print 'pop', key, args and arg[0] or '---'\n ... return super(Demo, self).pop(key, *args)\n ... def update(self, *args, **kwargs):\n ... print 'update'\n ... super(Demo, self).update(*args, **kwargs)\n ... def clear(self):\n ... print 'clear'\n ... super(Demo, self).clear()\n ...\n \n >>> demo1 = Demo()\n >>> demo2 = Demo([['foo', 'bar'], ['bing', 'baz']], sha='zam')\n update\n __setitem__ foo bar\n __setitem__ bing baz\n __setitem__ sha zam\n >>> demo2.setdefault('babble')\n __setitem__ babble None\n >>> del demo2['bing']\n pop bing ---\n >>> demo2.popitem()\n pop babble ---\n ('babble', None)\n >>> demo2.clear()\n clear\n\n\nRegression tests\n----------------\n\nWhen setting an item that's already in the dict, the length is not\nincreased:\n\n >>> d.clear()\n >>> d['foo'] = 'bar'\n >>> d['foo'] = 'baz'\n >>> len(d)\n 1\n\nLegacy tests\n------------\n\nOld databases may need to find something importable from zc.dict.ordered.\n\n >>> from zc.dict.ordered import OrderedDict as Olde\n >>> Olde is OrderedDict\n True", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "UNKNOWN", "keywords": "zope zope3", "license": "ZPL 2.1", "maintainer": null, "maintainer_email": null, "name": "zc.dict", "package_url": "https://pypi.org/project/zc.dict/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/zc.dict/", "project_urls": { "Download": "UNKNOWN", "Homepage": "UNKNOWN" }, "release_url": "https://pypi.org/project/zc.dict/1.2.1/", "requires_dist": null, "requires_python": null, "summary": "BTree-based persistent dict-like objects (regular dict and ordered) that can be\nused as base classes.\n\nThis is a bit of a heavyweight solution, as every zc.dict.Dict (and\nzc.dict.OrderedDict) is at least 3 persistent objects. Keep this in\nmind if you intend to create lots and lots of these.\n\nTo build, run ``python bootstrap/bootstrap.py`` and then ``bin/buildout``\nfrom this directory. A clean, non-system Python is strongly recommended.", "version": "1.2.1" }, "last_serial": 802171, "releases": { "1.1": [ { "comment_text": "", "digests": { "md5": "7cfc5e18e4788fb5f6a56eaa872db298", "sha256": "fbca3c961fbff0866706eedc31ef848015db784d7dcb728d47de70fd2efa647c" }, "downloads": -1, "filename": "zc.dict-1.1.tar.gz", "has_sig": false, "md5_digest": "7cfc5e18e4788fb5f6a56eaa872db298", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6684, "upload_time": "2007-12-16T06:37:14", "url": "https://files.pythonhosted.org/packages/1e/56/3ad9de9b432e01b3e1ad93f93e1712505d8632aaa40c728a5ef88b938c88/zc.dict-1.1.tar.gz" } ], "1.2": [ { "comment_text": "", "digests": { "md5": "2bdabf4e3d524e01cae4d188cb5ae98a", "sha256": "0525b38403cb6c3d20d7c076831a4efc76108a114a10973a20b13cc3b3e9dce1" }, "downloads": -1, "filename": "zc.dict-1.2.tar.gz", "has_sig": false, "md5_digest": "2bdabf4e3d524e01cae4d188cb5ae98a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9318, "upload_time": "2008-03-05T22:35:14", "url": "https://files.pythonhosted.org/packages/14/23/2d184ac0b3d1db8c79bfc20003bbf6576f02daf1f690508cc8984015eba0/zc.dict-1.2.tar.gz" } ], "1.2.1": [ { "comment_text": "", "digests": { "md5": "4adbf89069c502b3ec1ae9a2b8c96615", "sha256": "63ee101c87837551ff4046bf4538cd02609ea033bfff1513f42c67da1f552e79" }, "downloads": -1, "filename": "zc.dict-1.2.1.tar.gz", "has_sig": false, "md5_digest": "4adbf89069c502b3ec1ae9a2b8c96615", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10769, "upload_time": "2008-03-06T02:34:17", "url": "https://files.pythonhosted.org/packages/a1/13/b52dad4761048331e8a4198af50774c6cafde69d98aa965e1c2115e72791/zc.dict-1.2.1.tar.gz" } ], "1.3b1": [ { "comment_text": "", "digests": { "md5": "44c2ecce20979736fe71699f73865b4d", "sha256": "f074fc87777f0194ef6c2d89c25e6debf42f8a29ae1452574d2407e43bd999e0" }, "downloads": -1, "filename": "zc.dict-1.3b1.tar.gz", "has_sig": true, "md5_digest": "44c2ecce20979736fe71699f73865b4d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10029, "upload_time": "2009-03-16T20:41:06", "url": "https://files.pythonhosted.org/packages/93/08/3927f6b4cc2a284f8f17e1356ea3a34140ebb2d09f5766ba1cd640fdf859/zc.dict-1.3b1.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "4adbf89069c502b3ec1ae9a2b8c96615", "sha256": "63ee101c87837551ff4046bf4538cd02609ea033bfff1513f42c67da1f552e79" }, "downloads": -1, "filename": "zc.dict-1.2.1.tar.gz", "has_sig": false, "md5_digest": "4adbf89069c502b3ec1ae9a2b8c96615", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10769, "upload_time": "2008-03-06T02:34:17", "url": "https://files.pythonhosted.org/packages/a1/13/b52dad4761048331e8a4198af50774c6cafde69d98aa965e1c2115e72791/zc.dict-1.2.1.tar.gz" } ] }