[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