[Checkins] SVN: zope.copy/trunk/ Moved doctest examples to Sphinx docs.
Tres Seaver
cvs-admin at zope.org
Wed Jun 13 15:23:26 UTC 2012
Log message for revision 126845:
Moved doctest examples to Sphinx docs.
Changed:
_U zope.copy/trunk/
U zope.copy/trunk/CHANGES.txt
A zope.copy/trunk/docs/api.rst
U zope.copy/trunk/docs/index.rst
A zope.copy/trunk/docs/narr.rst
D zope.copy/trunk/src/zope/copy/README.txt
D zope.copy/trunk/src/zope/copy/pickling.txt
A zope.copy/trunk/src/zope/copy/tests/
A zope.copy/trunk/src/zope/copy/tests/__init__.py
A zope.copy/trunk/src/zope/copy/tests/test_copy.py
D zope.copy/trunk/src/zope/copy/tests.py
-=-
Modified: zope.copy/trunk/CHANGES.txt
===================================================================
--- zope.copy/trunk/CHANGES.txt 2012-06-13 15:23:19 UTC (rev 126844)
+++ zope.copy/trunk/CHANGES.txt 2012-06-13 15:23:23 UTC (rev 126845)
@@ -5,7 +5,7 @@
4.0.0 (unreleased)
------------------
-- Added Sphinx documentation.
+- Added Sphinx documentation: moved doctest examples to API reference.
- Added 'setup.py docs' alias (installs ``Sphinx`` and dependencies).
Added: zope.copy/trunk/docs/api.rst
===================================================================
--- zope.copy/trunk/docs/api.rst (rev 0)
+++ zope.copy/trunk/docs/api.rst 2012-06-13 15:23:23 UTC (rev 126845)
@@ -0,0 +1,13 @@
+:mod:`zope.copy` API Reference
+==============================
+
+:mod:`zope.copy.interfaces`
+---------------------------
+
+.. automodule:: zope.copy.interfaces
+
+ .. autoexception:: ResumeCopy
+
+ .. autointerface:: ICopyHook
+ :members:
+ :member-order: bysource
Modified: zope.copy/trunk/docs/index.rst
===================================================================
--- zope.copy/trunk/docs/index.rst 2012-06-13 15:23:19 UTC (rev 126844)
+++ zope.copy/trunk/docs/index.rst 2012-06-13 15:23:23 UTC (rev 126845)
@@ -6,6 +6,8 @@
.. toctree::
:maxdepth: 2
+ narr
+ api
Indices and tables
Added: zope.copy/trunk/docs/narr.rst
===================================================================
--- zope.copy/trunk/docs/narr.rst (rev 0)
+++ zope.copy/trunk/docs/narr.rst 2012-06-13 15:23:23 UTC (rev 126845)
@@ -0,0 +1,404 @@
+Using :mod:`zope.copy`
+======================
+
+
+Copying persistent objects
+--------------------------
+
+This package provides a pluggable way to copy persistent objects. It
+was once extracted from the zc.copy package to contain much less
+dependencies. In fact, we only depend on :mod:`zope.interface` to provide
+pluggability.
+
+The package provides a :func:`clone` function that does the object cloning
+and the :func:`copy` wrapper that sets :attr:`__parent__` and
+:attr:`__name__` attributes of object's copy to None. This is useful
+when working with Zope's located objects (see :mod:`zope.location` package).
+The :func:`copy` function actually calls the :func:`clone` function, so
+we'll use the first one in the examples below. We'll also look a bit at
+their differences in the end of this document.
+
+The :func:`clone` function (and thus the :func:`copy` function that wraps it)
+uses pickling to copy the object and all its subobjects recursively.
+As each object and subobject is pickled, the function tries to adapt it
+to :class:`zope.copy.interfaces.ICopyHook`. If a copy hook is found,
+the recursive copy is halted. The hook is called with two values: the
+main, top-level object that is being copied; and a callable that supports
+registering functions to be called after the copy is made. The copy hook
+should return the exact object or subobject that should be used at this
+point in the copy, or raise :exc:`zope.copy.interfaces.ResumeCopy`
+exception to resume copying the object or subobject recursively after
+all.
+
+Note that we use zope's component architecture provided by the
+:mod:`zope.component` package in this document, but the
+:mod:`zope.copy` package itself doesn't use or depend on it, so
+you can provide another adaptation mechanism as described in
+:mod:`zope.interface`'s adapter documentation.
+
+Simple hooks
+------------
+
+First let's examine a simple use. A hook is to support the use case of
+resetting the state of data that should be changed in a copy -- for
+instance, a log, or freezing or versioning data. The canonical way to
+do this is by storing the changable data on a special sub-object of the
+object that is to be copied. We'll look at a simple case of a subobject
+that should be converted to None when it is copied -- the way that the
+zc.freeze copier hook works. Also see the zc.objectlog copier module
+for a similar example.
+
+So, here is a simple object that stores a boolean on a special object.
+
+.. doctest::
+
+ >>> class Demo(object):
+ ... _frozen = None
+ ... def isFrozen(self):
+ ... return self._frozen is not None
+ ... def freeze(self):
+ ... self._frozen = Data()
+ ...
+ >>> class Data(object):
+ ... pass
+ ...
+
+Here's what happens if we copy one of these objects without a copy hook.
+
+.. doctest::
+
+ >>> original = Demo()
+ >>> original.isFrozen()
+ False
+ >>> original.freeze()
+ >>> original.isFrozen()
+ True
+ >>> import zope.copy
+ >>> copy = zope.copy.copy(original)
+ >>> copy is original
+ False
+ >>> copy.isFrozen()
+ True
+
+Now let's make a super-simple copy hook that always returns None, no
+matter what the top-level object being copied is. We'll register it and
+make another copy.
+
+.. doctest::
+
+ >>> import zope.component
+ >>> import zope.interface
+ >>> import zope.copy.interfaces
+ >>> def _factory(obj, register):
+ ... return None
+ >>> @zope.component.adapter(Data)
+ ... @zope.interface.implementer(zope.copy.interfaces.ICopyHook)
+ ... def data_copyfactory(obj):
+ ... return _factory
+ ...
+
+ >>> zope.component.provideAdapter(data_copyfactory)
+ >>> copy2 = zope.copy.copy(original)
+ >>> copy2 is original
+ False
+ >>> copy2.isFrozen()
+ False
+
+Much better.
+
+Post-copy functions
+-------------------
+
+Now, let's look at the registration function that the hook can use. It
+is useful for resetting objects within the new copy -- for instance, back
+references such as __parent__ pointers. This is used concretely in the
+zc.objectlog.copier module; we will come up with a similar but artificial
+example here.
+
+Imagine an object with a subobject that is "located" (i.e., zope.location) on
+the parent and should be replaced whenever the main object is copied.
+
+.. doctest::
+
+ >>> import zope.location.location
+ >>> class Subobject(zope.location.location.Location):
+ ... def __init__(self):
+ ... self.counter = 0
+ ... def __call__(self):
+ ... res = self.counter
+ ... self.counter += 1
+ ... return res
+ ...
+ >>> o = zope.location.location.Location()
+ >>> s = Subobject()
+ >>> o.subobject = s
+ >>> zope.location.location.locate(s, o, 'subobject')
+ >>> s.__parent__ is o
+ True
+ >>> o.subobject()
+ 0
+ >>> o.subobject()
+ 1
+ >>> o.subobject()
+ 2
+
+Without an ICopyHook, this will simply duplicate the subobject, with correct
+new pointers.
+
+.. doctest::
+
+ >>> c = zope.copy.copy(o)
+ >>> c.subobject.__parent__ is c
+ True
+
+Note that the subobject has also copied state.
+
+.. doctest::
+
+ >>> c.subobject()
+ 3
+ >>> o.subobject()
+ 3
+
+Our goal will be to make the counters restart when they are copied. We'll do
+that with a copy hook.
+
+This copy hook is different: it provides an object to replace the old object,
+but then it needs to set it up further after the copy is made. This is
+accomplished by registering a callable, :func:`reparent` here, that sets up
+the :attr:`__parent__`. The callable is passed a function that can translate
+something from the original object into the equivalent on the new object.
+We use this to find the new parent, so we can set it.
+
+.. doctest::
+
+ >>> import zope.component
+ >>> import zope.interface
+ >>> import zope.copy.interfaces
+ >>> @zope.component.adapter(Subobject)
+ ... @zope.interface.implementer(zope.copy.interfaces.ICopyHook)
+ ... def subobject_copyfactory(original):
+ ... def factory(obj, register):
+ ... obj = Subobject()
+ ... def reparent(translate):
+ ... obj.__parent__ = translate(original.__parent__)
+ ... register(reparent)
+ ... return obj
+ ... return factory
+ ...
+ >>> zope.component.provideAdapter(subobject_copyfactory)
+
+Now when we copy, the new subobject will have the correct, revised __parent__,
+but will be otherwise reset (here, just the counter)
+
+.. doctest::
+
+ >>> c = zope.copy.copy(o)
+ >>> c.subobject.__parent__ is c
+ True
+ >>> c.subobject()
+ 0
+ >>> o.subobject()
+ 4
+
+Resuming recursive copy
+-----------------------
+
+One thing we didn't examine yet is the use of ResumeCopy exception in
+the copy hooks. For example, when copying located objects we don't want
+to copy referenced subobjects that are not located in the object that
+is being copied. Imagine, we have a content object that has an image object,
+referenced by the :attr:`cover` attribute, but located in an independent
+place.
+
+.. doctest::
+
+ >>> root = zope.location.location.Location()
+
+ >>> content = zope.location.location.Location()
+ >>> zope.location.location.locate(content, root, 'content')
+
+ >>> image = zope.location.location.Location()
+ >>> zope.location.location.locate(image, root, 'image.jpg')
+
+ >>> content.cover = image
+
+Without any hooks, the image object will be cloned as well:
+
+.. doctest::
+
+ >>> new = zope.copy.copy(content)
+ >>> new.cover is image
+ False
+
+That's not what we'd expect though, so, let's provide a copy hook
+to deal with that. The copy hook for this case is provided by zope.location
+package, but we'll create one from scratch as we want to check out the
+usage of the ResumeCopy.
+
+.. doctest::
+
+ >>> @zope.component.adapter(zope.location.interfaces.ILocation)
+ ... @zope.interface.implementer(zope.copy.interfaces.ICopyHook)
+ ... def location_copyfactory(obj):
+ ... def factory(location, register):
+ ... if not zope.location.location.inside(obj, location):
+ ... return obj
+ ... raise zope.copy.interfaces.ResumeCopy
+ ... return factory
+ ...
+ >>> zope.component.provideAdapter(location_copyfactory)
+
+This hook returns objects as they are if they are not located inside
+object that's being copied, or raises ResumeCopy to signal that the
+recursive copy should be continued and used for the object.
+
+.. doctest::
+
+ >>> new = zope.copy.copy(content)
+ >>> new.cover is image
+ True
+
+Much better :-)
+
+:func:`clone` vs :func:`copy`
+------------------------------
+
+As we stated before, there's two functions that is used for copying
+objects. The :func:`clone` - that does the job, and its wrapper, :func:`copy`
+that calls :func:`clone` and then clears copy's :attr:`__parent__` and
+:attr:`__name__` attribute values.
+
+Let's create a location object with __name__ and __parent__ set.
+
+.. doctest::
+
+ >>> root = zope.location.location.Location()
+ >>> folder = zope.location.location.Location()
+ >>> folder.__name__ = 'files'
+ >>> folder.__parent__ = root
+
+The :func:`clone` function will leave those attributes as is. Note that the
+referenced __parent__ won't be cloned, as we registered a hook for locations
+in the previous section.
+
+.. doctest::
+
+ >>> folder_clone = zope.copy.clone(folder)
+ >>> folder_clone.__parent__ is root
+ True
+ >>> folder_clone.__name__ == 'files'
+ True
+
+However, the :func:`copy` function will reset those attributes to None, as
+we will probably want to place our object into another container with
+another name.
+
+.. doctest::
+
+ >>> folder_clone = zope.copy.copy(folder)
+ >>> folder_clone.__parent__ is None
+ True
+ >>> folder_clone.__name__ is None
+ True
+
+Notice, that if your object doesn't have __parent__ and __name__
+attributes at all, or these attributes could'nt be got or set because of
+some protections (as with zope.security's proxies, for example), you still
+can use the :func:`copy` function, because it works for objects that don't
+have those attributes.
+
+It won't set them if original object doesn't have them:
+
+.. doctest::
+
+ >>> class Something(object):
+ ... pass
+
+ >>> s = Something()
+ >>> s_copy = zope.copy.copy(s)
+ >>> s_copy.__parent__
+ Traceback (most recent call last):
+ ...
+ AttributeError: ...
+ >>> s_copy.__name__
+ Traceback (most recent call last):
+ ...
+ AttributeError: ...
+
+And it won't fail if original object has them but doesn't allow to set
+them.
+
+.. doctest::
+
+ >>> root = object()
+ >>> class Something(object):
+ ...
+ ... @apply
+ ... def __name__():
+ ... def fget(self):
+ ... return 'something'
+ ... def fset(self, value):
+ ... raise AttributeError
+ ... return property(fget, fset)
+ ...
+ ... @apply
+ ... def __parent__():
+ ... def fget(self):
+ ... return root
+ ... def fset(self, value):
+ ... raise AttributeError
+ ... return property(fget, fset)
+
+ >>> s = Something()
+ >>> s_copy = zope.copy.copy(s)
+ >>> s_copy.__parent__ is root
+ True
+ >>> s_copy.__name__ == 'something'
+ True
+
+:class:`~zope.location.pickling.LocationCopyHook`
+-------------------------------------------------
+
+The location copy hook is defined in :mod:`zope.location` but only activated
+if this package is installed.
+
+It's job is to allow copying referenced objects that are not located inside
+object that's being copied.
+
+To see the problem, imagine we want to copy an
+:class:`~zope.location.interfaces.ILocation` object that
+contains an attribute-based reference to another ILocation object
+and the referenced object is not contained inside object being copied.
+
+Without this hook, the referenced object will be cloned:
+
+.. doctest::
+
+ >>> from zope.location.location import Location, locate
+ >>> root = Location()
+ >>> page = Location()
+ >>> locate(page, root, 'page')
+ >>> image = Location()
+ >>> locate(page, root, 'image')
+ >>> page.thumbnail = image
+
+ >>> from zope.copy import copy
+ >>> page_copy = copy(page)
+ >>> page_copy.thumbnail is image
+ False
+
+But if we will provide a hook, the attribute will point to the
+original object as we might want.
+
+.. doctest::
+
+ >>> from zope.component import provideAdapter
+ >>> from zope.location.pickling import LocationCopyHook
+ >>> from zope.location.interfaces import ILocation
+ >>> provideAdapter(LocationCopyHook, (ILocation,))
+
+ >>> from zope.copy import copy
+ >>> page_copy = copy(page)
+ >>> page_copy.thumbnail is image
+ True
Deleted: zope.copy/trunk/src/zope/copy/README.txt
===================================================================
--- zope.copy/trunk/src/zope/copy/README.txt 2012-06-13 15:23:19 UTC (rev 126844)
+++ zope.copy/trunk/src/zope/copy/README.txt 2012-06-13 15:23:23 UTC (rev 126845)
@@ -1,321 +0,0 @@
-==============
-Object copying
-==============
-
-This package provides a pluggable way to copy persistent objects. It
-was once extracted from the zc.copy package to contain much less
-dependencies. In fact, we only depend on zope.interface to provide
-pluggability.
-
-The package provides a ``clone`` function that does the object cloning
-and the ``copy`` wrapper that sets __parent__ and __name__ attributes
-of object's copy to None. This is useful, when working with Zope's
-located objects (see zope.location package). The ``copy`` function
-actually calls the ``clone`` function so we'll use the first one in
-the examples below. We'll also look a bit at their differences in the
-end of this document.
-
-The ``clone`` function (and thus the ``copy`` function that wraps it)
-uses pickling to copy the object and all its subobjects recursively.
-As each object and subobject is pickled, the function tries to adapt it
-to ``zope.copy.interfaces.ICopyHook``. If a copy hook is found,
-the recursive copy is halted. The hook is called with two values: the
-main, top-level object that is being copied; and a callable that supports
-registering functions to be called after the copy is made. The copy hook
-should return the exact object or subobject that should be used at this
-point in the copy, or raise ``zope.copy.interfaces.ResumeCopy``
-exception to resume copying the object or subobject recursively after
-all.
-
-Note that we use zope's component architecture provided by the
-``zope.component`` package in this document, but the
-``zope.copy`` package itself doesn't use or depend on it, so
-you can provide another adaptation mechanism as described in zope.interface's
-adapter documentation.
-
-Simple hooks
-------------
-
-First let's examine a simple use. A hook is to support the use case of
-resetting the state of data that should be changed in a copy -- for
-instance, a log, or freezing or versioning data. The canonical way to
-do this is by storing the changable data on a special sub-object of the
-object that is to be copied. We'll look at a simple case of a subobject
-that should be converted to None when it is copied -- the way that the
-zc.freeze copier hook works. Also see the zc.objectlog copier module
-for a similar example.
-
-So, here is a simple object that stores a boolean on a special object.
-
- >>> class Demo(object):
- ... _frozen = None
- ... def isFrozen(self):
- ... return self._frozen is not None
- ... def freeze(self):
- ... self._frozen = Data()
- ...
- >>> class Data(object):
- ... pass
- ...
-
-Here's what happens if we copy one of these objects without a copy hook.
-
- >>> original = Demo()
- >>> original.isFrozen()
- False
- >>> original.freeze()
- >>> original.isFrozen()
- True
- >>> import zope.copy
- >>> copy = zope.copy.copy(original)
- >>> copy is original
- False
- >>> copy.isFrozen()
- True
-
-Now let's make a super-simple copy hook that always returns None, no
-matter what the top-level object being copied is. We'll register it and
-make another copy.
-
- >>> import zope.component
- >>> import zope.interface
- >>> import zope.copy.interfaces
- >>> def _factory(obj, register):
- ... return None
- >>> @zope.component.adapter(Data)
- ... @zope.interface.implementer(zope.copy.interfaces.ICopyHook)
- ... def data_copyfactory(obj):
- ... return _factory
- ...
-
- >>> zope.component.provideAdapter(data_copyfactory)
- >>> copy2 = zope.copy.copy(original)
- >>> copy2 is original
- False
- >>> copy2.isFrozen()
- False
-
-Much better.
-
-Post-copy functions
--------------------
-
-Now, let's look at the registration function that the hook can use. It
-is useful for resetting objects within the new copy -- for instance, back
-references such as __parent__ pointers. This is used concretely in the
-zc.objectlog.copier module; we will come up with a similar but artificial
-example here.
-
-Imagine an object with a subobject that is "located" (i.e., zope.location) on
-the parent and should be replaced whenever the main object is copied.
-
- >>> import zope.location.location
- >>> class Subobject(zope.location.location.Location):
- ... def __init__(self):
- ... self.counter = 0
- ... def __call__(self):
- ... res = self.counter
- ... self.counter += 1
- ... return res
- ...
- >>> o = zope.location.location.Location()
- >>> s = Subobject()
- >>> o.subobject = s
- >>> zope.location.location.locate(s, o, 'subobject')
- >>> s.__parent__ is o
- True
- >>> o.subobject()
- 0
- >>> o.subobject()
- 1
- >>> o.subobject()
- 2
-
-Without an ICopyHook, this will simply duplicate the subobject, with correct
-new pointers.
-
- >>> c = zope.copy.copy(o)
- >>> c.subobject.__parent__ is c
- True
-
-Note that the subobject has also copied state.
-
- >>> c.subobject()
- 3
- >>> o.subobject()
- 3
-
-Our goal will be to make the counters restart when they are copied. We'll do
-that with a copy hook.
-
-This copy hook is different: it provides an object to replace the old object,
-but then it needs to set it up further after the copy is made. This is
-accomplished by registering a callable, ``reparent`` here, that sets up the
-__parent__. The callable is passed a function that can translate something
-from the original object into the equivalent on the new object. We use this
-to find the new parent, so we can set it.
-
- >>> import zope.component
- >>> import zope.interface
- >>> import zope.copy.interfaces
- >>> @zope.component.adapter(Subobject)
- ... @zope.interface.implementer(zope.copy.interfaces.ICopyHook)
- ... def subobject_copyfactory(original):
- ... def factory(obj, register):
- ... obj = Subobject()
- ... def reparent(translate):
- ... obj.__parent__ = translate(original.__parent__)
- ... register(reparent)
- ... return obj
- ... return factory
- ...
- >>> zope.component.provideAdapter(subobject_copyfactory)
-
-Now when we copy, the new subobject will have the correct, revised __parent__,
-but will be otherwise reset (here, just the counter)
-
- >>> c = zope.copy.copy(o)
- >>> c.subobject.__parent__ is c
- True
- >>> c.subobject()
- 0
- >>> o.subobject()
- 4
-
-Resuming recursive copy
------------------------
-
-One thing we didn't examine yet is the use of ResumeCopy exception in
-the copy hooks. For example, when copying located objects we don't want
-to copy referenced subobjects that are not located in the object that
-is being copied. Imagine, we have a content object that has an image object,
-referenced by the ``cover`` attribute, but located in an independent
-place.
-
- >>> root = zope.location.location.Location()
-
- >>> content = zope.location.location.Location()
- >>> zope.location.location.locate(content, root, 'content')
-
- >>> image = zope.location.location.Location()
- >>> zope.location.location.locate(image, root, 'image.jpg')
-
- >>> content.cover = image
-
-Without any hooks, the image object will be cloned as well:
-
- >>> new = zope.copy.copy(content)
- >>> new.cover is image
- False
-
-That's not what we'd expect though, so, let's provide a copy hook
-to deal with that. The copy hook for this case is provided by zope.location
-package, but we'll create one from scratch as we want to check out the
-usage of the ResumeCopy.
-
- >>> @zope.component.adapter(zope.location.interfaces.ILocation)
- ... @zope.interface.implementer(zope.copy.interfaces.ICopyHook)
- ... def location_copyfactory(obj):
- ... def factory(location, register):
- ... if not zope.location.location.inside(obj, location):
- ... return obj
- ... raise zope.copy.interfaces.ResumeCopy
- ... return factory
- ...
- >>> zope.component.provideAdapter(location_copyfactory)
-
-This hook returns objects as they are if they are not located inside
-object that's being copied, or raises ResumeCopy to signal that the
-recursive copy should be continued and used for the object.
-
- >>> new = zope.copy.copy(content)
- >>> new.cover is image
- True
-
-Much better :-)
-
-``clone`` vs ``copy``
----------------------
-
-As we stated before, there's two functions that is used for copying
-objects. The ``clone`` - that does the job, and its wrapper, ``copy``
-that calls ``clone`` and then clears copy's __parent__ and __name__
-attribute values.
-
-Let's create a location object with __name__ and __parent__ set.
-
- >>> root = zope.location.location.Location()
- >>> folder = zope.location.location.Location()
- >>> folder.__name__ = 'files'
- >>> folder.__parent__ = root
-
-The ``clone`` function will leave those attributes as is. Note that the
-referenced __parent__ won't be cloned, as we registered a hook for locations
-in the previous section.
-
- >>> folder_clone = zope.copy.clone(folder)
- >>> folder_clone.__parent__ is root
- True
- >>> folder_clone.__name__ == 'files'
- True
-
-However, the ``copy`` function will reset those attributes to None, as
-we will probably want to place our object into another container with
-another name.
-
- >>> folder_clone = zope.copy.copy(folder)
- >>> folder_clone.__parent__ is None
- True
- >>> folder_clone.__name__ is None
- True
-
-Notice, that if your object doesn't have __parent__ and __name__
-attributes at all, or these attributes could'nt be got or set because of
-some protections (as with zope.security's proxies, for example), you still
-can use the ``copy`` function, because it works for objects that don't
-have those attributes.
-
-It won't set them if original object doesn't have them:
-
- >>> class Something(object):
- ... pass
-
- >>> s = Something()
- >>> s_copy = zope.copy.copy(s)
- >>> s_copy.__parent__
- Traceback (most recent call last):
- ...
- AttributeError: ...
- >>> s_copy.__name__
- Traceback (most recent call last):
- ...
- AttributeError: ...
-
-And it won't fail if original object has them but doesn't allow to set
-them.
-
- >>> root = object()
- >>> class Something(object):
- ...
- ... @apply
- ... def __name__():
- ... def fget(self):
- ... return 'something'
- ... def fset(self, value):
- ... raise AttributeError
- ... return property(fget, fset)
- ...
- ... @apply
- ... def __parent__():
- ... def fget(self):
- ... return root
- ... def fset(self, value):
- ... raise AttributeError
- ... return property(fget, fset)
-
- >>> s = Something()
- >>> s_copy = zope.copy.copy(s)
- >>> s_copy.__parent__ is root
- True
- >>> s_copy.__name__ == 'something'
- True
Deleted: zope.copy/trunk/src/zope/copy/pickling.txt
===================================================================
--- zope.copy/trunk/src/zope/copy/pickling.txt 2012-06-13 15:23:19 UTC (rev 126844)
+++ zope.copy/trunk/src/zope/copy/pickling.txt 2012-06-13 15:23:23 UTC (rev 126845)
@@ -1,40 +0,0 @@
-LocationCopyHook
-================
-
-The location copy hook is defined in zope.location but only activated if this
-package is installed.
-
-It's job is to allow copying referenced objects that are not located inside
-object that's being copied.
-
-To see the problem, imagine we want to copy an ILocation object that
-contains an attribute-based reference to another ILocation object
-and the referenced object is not contained inside object being copied.
-
-Without this hook, the referenced object will be cloned:
-
- >>> from zope.location.location import Location, locate
- >>> root = Location()
- >>> page = Location()
- >>> locate(page, root, 'page')
- >>> image = Location()
- >>> locate(page, root, 'image')
- >>> page.thumbnail = image
-
- >>> from zope.copy import copy
- >>> page_copy = copy(page)
- >>> page_copy.thumbnail is image
- False
-
-But if we will provide a hook, the attribute will point to the
-original object as we might want.
-
- >>> from zope.component import provideAdapter
- >>> from zope.location.pickling import LocationCopyHook
- >>> from zope.location.interfaces import ILocation
- >>> provideAdapter(LocationCopyHook, (ILocation,))
-
- >>> from zope.copy import copy
- >>> page_copy = copy(page)
- >>> page_copy.thumbnail is image
- True
Added: zope.copy/trunk/src/zope/copy/tests/__init__.py
===================================================================
--- zope.copy/trunk/src/zope/copy/tests/__init__.py (rev 0)
+++ zope.copy/trunk/src/zope/copy/tests/__init__.py 2012-06-13 15:23:23 UTC (rev 126845)
@@ -0,0 +1 @@
+#package
Added: zope.copy/trunk/src/zope/copy/tests/test_copy.py
===================================================================
--- zope.copy/trunk/src/zope/copy/tests/test_copy.py (rev 0)
+++ zope.copy/trunk/src/zope/copy/tests/test_copy.py 2012-06-13 15:23:23 UTC (rev 126845)
@@ -0,0 +1,19 @@
+##############################################################################
+#
+# Copyright (c) 2012 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+import unittest
+
+
+def test_suite():
+ return unittest.TestSuite((
+ ))
Deleted: zope.copy/trunk/src/zope/copy/tests.py
===================================================================
--- zope.copy/trunk/src/zope/copy/tests.py 2012-06-13 15:23:19 UTC (rev 126844)
+++ zope.copy/trunk/src/zope/copy/tests.py 2012-06-13 15:23:23 UTC (rev 126845)
@@ -1,37 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2001, 2002 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Tests for the zope.copy package.
-"""
-import unittest
-import zope.component.testing
-from zope.testing import doctest, module
-
-def setUp(test):
- module.setUp(test, 'zope.copy.doctest')
-
-def tearDown(test):
- module.tearDown(test)
- zope.component.testing.tearDown()
-
-def test_suite():
- return unittest.TestSuite((
- doctest.DocFileSuite('pickling.txt',
- setUp=setUp,
- tearDown=tearDown,
- optionflags=doctest.ELLIPSIS|doctest.NORMALIZE_WHITESPACE),
- doctest.DocFileSuite('README.txt',
- setUp=setUp,
- tearDown=tearDown,
- optionflags=doctest.ELLIPSIS|doctest.NORMALIZE_WHITESPACE),
- ))
More information about the checkins
mailing list