{ "info": { "author": "Roger Ineichen, Stephan Richter and the Zope Community", "author_email": "zope3-dev@zope.org", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Environment :: Web Environment", "Framework :: Zope3", "Intended Audience :: Developers", "License :: OSI Approved :: Zope Public License", "Natural Language :: English", "Operating System :: OS Independent", "Programming Language :: Python", "Topic :: Internet :: WWW/HTTP" ], "description": "This package provides a proxy container implementation for Zope3.\n\n\n.. contents::\n\n=========\nz3c.proxy\n=========\n\nWe can proxy a regular container derived from zope's btree container for\nexample:\n\n >>> from zope.container.interfaces import IContainer\n >>> from zope.container.btree import BTreeContainer\n >>> container = BTreeContainer()\n >>> container.__name__, container.__parent__ = u'c1', u'p1'\n\n >>> from z3c.proxy import interfaces\n >>> from z3c.proxy.container import LocationProxy\n >>> from z3c.proxy.container import ContainerLocationProxy\n >>> proxy = ContainerLocationProxy(container)\n\nThe name and the parent of the proxy is None. The proxy provides\nIContainer:\n\n >>> proxy.__name__ is None\n True\n >>> proxy.__parent__ is None\n True\n >>> IContainer.providedBy(proxy)\n True\n >>> interfaces.IContainerLocationProxy.providedBy(proxy)\n True\n\nFirst we check the empty proxy:\n\n >>> proxy['x']\n Traceback (most recent call last):\n ...\n KeyError: 'x'\n\n >>> 'x' in proxy\n False\n\n >>> proxy.has_key('x')\n 0\n\n >>> [key for key in proxy.keys()]\n []\n\n >>> [item for item in proxy.items()]\n []\n\n >>> proxy.get('x') is None\n True\n\n >>> iterator = iter(proxy)\n >>> iterator.next()\n Traceback (most recent call last):\n ...\n StopIteration\n\n >>> proxy.values()\n []\n\n >>> len(proxy)\n 0\n\n >>> del proxy['x']\n Traceback (most recent call last):\n ...\n KeyError: 'x'\n\n >>> from zope.container.contained import Contained\n >>> proxy['x'] = x = Contained()\n\nNow we added our first item. This item should be added to the container.\nIts name will be x and its parent is the container itself:\n\n >>> x is container['x']\n True\n\n >>> x.__name__\n u'x'\n\n >>> x.__parent__ is container\n True\n\nIf we lookup 'x' within the proxy we do not get the blank 'x' but rather\nthe proxied 'x'. The proxy is not 'x' but only equal to 'x':\n\n >>> x is proxy['x']\n False\n\n >>> x == proxy['x']\n True\n\n >>> x1 = proxy['x']\n >>> from zope.proxy import isProxy\n >>> isProxy(x1)\n True\n\n >>> isinstance(x1, LocationProxy)\n True\n\nThe proxied 'x' has still the same name but not the same parent:\n\n >>> x1.__name__\n u'x'\n\n >>> x1.__parent__ is container\n False\n\n >>> x1.__parent__ is proxy\n True\n\nIf we add a second item to the container, it should appear in the\nproxy, too. But this item is proxied as container location proxy:\n\n >>> container['y'] = y = BTreeContainer()\n >>> y1 = proxy['y']\n >>> y1 is y\n False\n\n >>> y1 == y\n True\n\n >>> isinstance(y1, ContainerLocationProxy)\n True\n\nThe container location proxy is able to proxy the location of\nnested objects:\n\n >>> proxy['y']['z'] = z = Contained()\n >>> container['y']['z'] is z\n True\n\n >>> z1 = y1['z']\n >>> z1 is z\n False\n\n >>> z1 == z\n True\n\n >>> isinstance(z1, LocationProxy)\n True\n\n >>> z1.__parent__ is y1\n True\n\nFinaly we check all other methods of the proxy:\n\n >>> 'x' in proxy\n True\n\n >>> proxy.has_key('x')\n 1\n\n >>> keys = [key for key in proxy.keys()]; keys.sort(); keys\n [u'x', u'y']\n\n >>> items = [item for item in proxy.items()]; items.sort()\n >>> items == [(u'x', x), (u'y', y)]\n True\n\n >>> proxy.get('x') == x\n True\n\n >>> iterator = iter(proxy)\n >>> iterator.next() in proxy\n True\n\n >>> iterator.next() in proxy\n True\n\n >>> iterator.next()\n Traceback (most recent call last):\n ...\n StopIteration\n\n >>> values = proxy.values(); values.sort();\n >>> x in values, y in values\n (True, True)\n\n >>> len(proxy)\n 2\n\n >>> del proxy['x']\n >>> 'x' in proxy\n False\n\n\nObjectMover\n-----------\n\nTo use an object mover, pass a contained ``object`` to the class. The\ncontained ``object`` should implement ``IContained``. It should be contained\nin a container that has an adapter to ``INameChooser``.\n\nSetup test container and proxies:\n\n >>> from zope.interface import implements\n >>> from zope.container.interfaces import INameChooser\n >>> from zope.copypastemove import ExampleContainer\n >>> from z3c.proxy.container import ProxyAwareObjectMover\n\n >>> class ContainerLocationProxyStub(ContainerLocationProxy):\n ...\n ... implements(INameChooser)\n ...\n ... def chooseName(self, name, ob):\n ... while name in self:\n ... name += '_'\n ... return name\n\n >>> container = ExampleContainer()\n >>> container2 = ExampleContainer()\n\n >>> ob = Contained()\n >>> proxy = ContainerLocationProxyStub(container)\n >>> proxy[u'foo'] = ob\n >>> ob = proxy[u'foo']\n >>> mover = ProxyAwareObjectMover(ob)\n\nIn addition to moving objects, object movers can tell you if the object is\nmovable:\n\n >>> mover.moveable()\n 1\n\nwhich, at least for now, they always are. A better question to ask is whether\nwe can move to a particular container. Right now, we can always move to a\ncontainer of the same class:\n\n >>> proxy2 = ContainerLocationProxyStub(container2)\n >>> mover.moveableTo(proxy2)\n 1\n\n >>> mover.moveableTo({})\n Traceback (most recent call last):\n ...\n TypeError: Container is not a valid Zope container.\n\nOf course, once we've decided we can move an object, we can use the mover to\ndo so:\n\n >>> mover.moveTo(proxy2)\n u'foo'\n\n >>> list(proxy)\n []\n\n >>> list(proxy2)\n [u'foo']\n\n >>> ob = proxy2[u'foo']\n >>> ob.__parent__ is proxy2\n True\n\nWe can also specify a name:\n\n >>> mover.moveTo(proxy2, u'bar')\n u'bar'\n\n >>> list(proxy2)\n [u'bar']\n\n >>> ob = proxy2[u'bar']\n >>> ob.__parent__ is proxy2\n True\n\n >>> ob.__name__\n u'bar'\n\nBut we may not use the same name given, if the name is already in use:\n\n >>> proxy2[u'splat'] = 1\n >>> mover.moveTo(proxy2, u'splat')\n u'splat_'\n\n >>> l = list(proxy2)\n >>> l.sort()\n >>> l\n [u'splat', u'splat_']\n\n >>> ob = proxy2[u'splat_']\n >>> ob.__name__\n u'splat_'\n\nIf we try to move to an invalid container, we'll get an error:\n\n >>> mover.moveTo({})\n Traceback (most recent call last):\n ...\n TypeError: Container is not a valid Zope container.\n\n\nObjectCopier\n------------\n\nTo use an object copier, pass a contained ``object`` to the class. The\ncontained ``object`` should implement ``IContained``. It should be contained\nin a container that has an adapter to `INameChooser`.\n\nSetup test container and proxies:\n\n >>> from z3c.proxy.container import ProxyAwareObjectCopier\n >>> class ContainerLocationProxyStub(ContainerLocationProxy):\n ...\n ... implements(INameChooser)\n ...\n ... def chooseName(self, name, ob):\n ... while name in self:\n ... name += '_'\n ... return name\n\n\n >>> container = ExampleContainer()\n >>> container2 = ExampleContainer()\n\n >>> proxy = ContainerLocationProxyStub(container)\n >>> proxy[u'foo'] = ob = Contained()\n >>> ob = proxy[u'foo']\n >>> copier = ProxyAwareObjectCopier(ob)\n\nIn addition to moving objects, object copiers can tell you if the object is\nmovable:\n\n >>> copier.copyable()\n 1\n\nwhich, at least for now, they always are. A better question to ask is whether\nwe can copy to a particular container. Right now, we can always copy to a\ncontainer of the same class:\n\n >>> proxy2 = ContainerLocationProxyStub(container2)\n >>> copier.copyableTo(proxy2)\n 1\n\n >>> copier.copyableTo({})\n Traceback (most recent call last):\n ...\n TypeError: Container is not a valid Zope container.\n\nOf course, once we've decided we can copy an object, we can use the copier to\ndo so:\n\n >>> copier.copyTo(proxy2)\n u'foo'\n\n >>> list(proxy)\n [u'foo']\n\n >>> list(proxy2)\n [u'foo']\n\n >>> ob.__parent__ is proxy\n 1\n\n >>> proxy2[u'foo'] is ob\n 0\n\n >>> proxy2[u'foo'].__parent__ is proxy2\n 1\n\n >>> proxy2[u'foo'].__name__\n u'foo'\n\nWe can also specify a name:\n\n >>> copier.copyTo(proxy2, u'bar')\n u'bar'\n\n >>> l = list(proxy2)\n >>> l.sort()\n >>> l\n [u'bar', u'foo']\n\n >>> ob.__parent__ is proxy\n 1\n\n >>> proxy2[u'bar'] is ob\n 0\n\n >>> proxy2[u'bar'].__parent__ is proxy2\n 1\n\n >>> proxy2[u'bar'].__name__\n u'bar'\n\nBut we may not use the same name given, if the name is already in use:\n\n >>> copier.copyTo(proxy2, u'bar')\n u'bar_'\n\n >>> l = list(proxy2)\n >>> l.sort()\n >>> l\n [u'bar', u'bar_', u'foo']\n\n >>> proxy2[u'bar_'].__name__\n u'bar_'\n\n\nIf we try to copy to an invalid container, we'll get an error:\n\n >>> copier.copyTo({})\n Traceback (most recent call last):\n ...\n TypeError: Container is not a valid Zope container.\n\n\nProxyAwareContainerItemRenamer\n------------------------------\n\nThis adapter uses IObjectMover to move an item within the same container to\na different name. We need to first setup an adapter for IObjectMover:\n\nSetup test container and proxies:\n\n >>> from zope.container.sample import SampleContainer\n >>> from zope.copypastemove import ContainerItemRenamer\n >>> from zope.copypastemove import IObjectMover\n >>> from z3c.proxy.container import ProxyAwareContainerItemRenamer\n\n >>> import zope.component\n >>> from zope.container.interfaces import IContained\n >>> zope.component.provideAdapter(ProxyAwareObjectMover, [IContained],\n ... IObjectMover)\n\n >>> class ContainerLocationProxyStub(ContainerLocationProxy):\n ...\n ... implements(INameChooser)\n ...\n ... def chooseName(self, name, ob):\n ... while name in self:\n ... name += '_'\n ... return name\n\nTo rename an item in a container, instantiate a ContainerItemRenamer with the\ncontainer:\n\n >>> container = SampleContainer()\n >>> proxy = ContainerLocationProxyStub(container)\n >>> renamer = ProxyAwareContainerItemRenamer(container)\n\nFor this example, we'll rename an item 'foo':\n\n >>> from z3c.proxy.container import _unproxy\n >>> foo = Contained()\n >>> proxy['foo'] = foo\n >>> proxy['foo'] == _unproxy(foo)\n True\n\nto 'bar':\n\n >>> renamer.renameItem('foo', 'bar')\n >>> proxy['foo'] is foo\n Traceback (most recent call last):\n KeyError: 'foo'\n\n >>> proxy['bar'] == _unproxy(foo)\n True\n\nIf the item being renamed isn't in the container, a NotFoundError is raised:\n\n >>> renamer.renameItem('foo', 'bar') # doctest:+ELLIPSIS\n Traceback (most recent call last):\n ItemNotFoundError: (<...SampleContainer...>, 'foo')\n\nIf the new item name already exists, a DuplicationError is raised:\n\n >>> renamer.renameItem('bar', 'bar')\n Traceback (most recent call last):\n DuplicationError: bar is already in use\n\n\n=======\nCHANGES\n=======\n\n0.6.1 (2010-08-23)\n------------------\n\n- Added doctest to `long_description` to render on PyPI.\n\n\n0.6.0 (2010-08-23)\n------------------\n\n- Replaced ``zope.app.container`` by ``zope.container``.\n\n- Using Python's ``doctest`` module instead of deprecated\n ``zope.testing.doctestunit``.\n\n0.5.0 (2008-04-12)\n------------------\n\n- Initial Release", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "http://cheeseshop.python.org/pypi/z3c.proxy", "keywords": "zope3 z3c container proxy", "license": "ZPL 2.1", "maintainer": null, "maintainer_email": null, "name": "z3c.proxy", "package_url": "https://pypi.org/project/z3c.proxy/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/z3c.proxy/", "project_urls": { "Download": "UNKNOWN", "Homepage": "http://cheeseshop.python.org/pypi/z3c.proxy" }, "release_url": "https://pypi.org/project/z3c.proxy/0.6.1/", "requires_dist": null, "requires_python": null, "summary": "Container proxy implementation for Zope3", "version": "0.6.1" }, "last_serial": 802067, "releases": { "0.5.0": [ { "comment_text": "", "digests": { "md5": "8399114eed5d41c49240aa9ebdd81b90", "sha256": "071599c765e32ae08f9477a394034e063cad1e4d93f3b544968275f2a44d503e" }, "downloads": -1, "filename": "z3c.proxy-0.5.0.zip", "has_sig": false, "md5_digest": "8399114eed5d41c49240aa9ebdd81b90", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13975, "upload_time": "2008-04-12T19:49:05", "url": "https://files.pythonhosted.org/packages/d2/7f/25318eeda46046eedae64f1f356e080d6cd6890eca2afc74393d999bf765/z3c.proxy-0.5.0.zip" } ], "0.6.0": [ { "comment_text": "", "digests": { "md5": "ce66336a7fcd1d12031abd9e0fb50046", "sha256": "b4b6b06eb0f546bb97e35fce95af70f42e46af754725c58f718371c367fdbde0" }, "downloads": -1, "filename": "z3c.proxy-0.6.0.tar.gz", "has_sig": false, "md5_digest": "ce66336a7fcd1d12031abd9e0fb50046", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8117, "upload_time": "2010-08-23T08:21:42", "url": "https://files.pythonhosted.org/packages/69/fe/120c58cf3872c6a466fde382b24c590e545d3c53d536504b735b0f69fc42/z3c.proxy-0.6.0.tar.gz" } ], "0.6.1": [ { "comment_text": "", "digests": { "md5": "84883a54f6377572b28aa0a0705240d1", "sha256": "d8c8cb09747ace2c2634effcd7979f3f192c9f9a65bb4fd8baf24c103af94c7d" }, "downloads": -1, "filename": "z3c.proxy-0.6.1.tar.gz", "has_sig": false, "md5_digest": "84883a54f6377572b28aa0a0705240d1", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9636, "upload_time": "2010-08-23T08:23:24", "url": "https://files.pythonhosted.org/packages/f0/ad/9493d5f4a7761f67349ffdd883a61c6f179d258f1a9d830fd444ff11a9e9/z3c.proxy-0.6.1.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "84883a54f6377572b28aa0a0705240d1", "sha256": "d8c8cb09747ace2c2634effcd7979f3f192c9f9a65bb4fd8baf24c103af94c7d" }, "downloads": -1, "filename": "z3c.proxy-0.6.1.tar.gz", "has_sig": false, "md5_digest": "84883a54f6377572b28aa0a0705240d1", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9636, "upload_time": "2010-08-23T08:23:24", "url": "https://files.pythonhosted.org/packages/f0/ad/9493d5f4a7761f67349ffdd883a61c6f179d258f1a9d830fd444ff11a9e9/z3c.proxy-0.6.1.tar.gz" } ] }