[Checkins] SVN: zope.location/tags/3.5.1/ Tag 3.5.1
Dan Korostelev
nadako at gmail.com
Mon Feb 2 07:16:54 EST 2009
Log message for revision 95961:
Tag 3.5.1
Changed:
A zope.location/tags/3.5.1/
D zope.location/tags/3.5.1/CHANGES.txt
A zope.location/tags/3.5.1/CHANGES.txt
U zope.location/tags/3.5.1/setup.py
D zope.location/tags/3.5.1/src/
A zope.location/tags/3.5.1/src/
D zope.location/tags/3.5.1/src/zope/location/interfaces.py
A zope.location/tags/3.5.1/src/zope/location/interfaces.py
D zope.location/tags/3.5.1/src/zope/location/location.txt
A zope.location/tags/3.5.1/src/zope/location/location.txt
D zope.location/tags/3.5.1/src/zope/location/pickling.py
A zope.location/tags/3.5.1/src/zope/location/pickling.py
D zope.location/tags/3.5.1/src/zope/location/traversing.py
A zope.location/tags/3.5.1/src/zope/location/traversing.py
-=-
Deleted: zope.location/tags/3.5.1/CHANGES.txt
===================================================================
--- zope.location/trunk/CHANGES.txt 2009-02-02 10:59:25 UTC (rev 95958)
+++ zope.location/tags/3.5.1/CHANGES.txt 2009-02-02 12:16:54 UTC (rev 95961)
@@ -1,32 +0,0 @@
-=======
-CHANGES
-=======
-
-3.5.1 (unreleased)
-------------------
-
-- Improve test coverage.
-
-- The new ``getParents`` method was extracted from ``zope.traversing``
- and added to ILocationInfo interface in the previous release. Custom
- ILocationInfo implementations should make sure they have this method
- as well. That method is already used in ``zope.traversing.api.getParents``
- function.
-
-- Make ``getName`` of ILocationInfo always return empty string for
- the IRoot object, like RootPhysicallyLocatable from zope.traversing
- did, making the latter one obsolete.
-
-- Change package mailing list address to zope-dev at zope.org instead
- of retired zope3-dev at zope.org.
-
-3.5.0 (2009-01-31)
-------------------
-
-- Reverse the dependency between zope.location and zope.traversing. This
- also causes the dependency to various other packages go away.
-
-3.4.0 (2007-10-02)
-------------------
-
-- Initial release independent of the main Zope tree.
Copied: zope.location/tags/3.5.1/CHANGES.txt (from rev 95960, zope.location/trunk/CHANGES.txt)
===================================================================
--- zope.location/tags/3.5.1/CHANGES.txt (rev 0)
+++ zope.location/tags/3.5.1/CHANGES.txt 2009-02-02 12:16:54 UTC (rev 95961)
@@ -0,0 +1,34 @@
+=======
+CHANGES
+=======
+
+3.5.1 (2009-02-02)
+------------------
+
+- Improve test coverage.
+
+- The new ``getParents`` method was extracted from ``zope.traversing``
+ and added to ILocationInfo interface in the previous release. Custom
+ ILocationInfo implementations should make sure they have this method
+ as well. That method is already used in ``zope.traversing.api.getParents``
+ function.
+
+- Make ``getName`` of LocationPhysicallyLocatable always return empty
+ string for the IRoot object, like RootPhysicallyLocatable from
+ ``zope.traversing`` did. So, now LocationPhysicallyLocatable is
+ fully compatible with RootPhysicallyLocatable, making the latter one
+ obsolete.
+
+- Change package mailing list address to zope-dev at zope.org instead
+ of retired zope3-dev at zope.org.
+
+3.5.0 (2009-01-31)
+------------------
+
+- Reverse the dependency between zope.location and zope.traversing. This
+ also causes the dependency to various other packages go away.
+
+3.4.0 (2007-10-02)
+------------------
+
+- Initial release independent of the main Zope tree.
Modified: zope.location/tags/3.5.1/setup.py
===================================================================
--- zope.location/trunk/setup.py 2009-02-02 10:59:25 UTC (rev 95958)
+++ zope.location/tags/3.5.1/setup.py 2009-02-02 12:16:54 UTC (rev 95961)
@@ -21,7 +21,7 @@
return text
setup(name='zope.location',
- version = '3.5.1dev',
+ version = '3.5.1',
author='Zope Corporation and Contributors',
author_email='zope-dev at zope.org',
description='Zope Location',
Deleted: zope.location/tags/3.5.1/src/zope/location/interfaces.py
===================================================================
--- zope.location/trunk/src/zope/location/interfaces.py 2009-02-02 06:01:56 UTC (rev 95956)
+++ zope.location/tags/3.5.1/src/zope/location/interfaces.py 2009-02-02 12:16:54 UTC (rev 95961)
@@ -1,143 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2003-2009 Zope Corporation 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.
-#
-##############################################################################
-"""Location framework interfaces
-
-$Id$
-"""
-__docformat__ = 'restructuredtext'
-
-import zope.interface
-import zope.schema
-
-_RAISE_KEYERROR = object()
-
-
-class ILocation(zope.interface.Interface):
- """Objects that can be located in a hierachy.
-
- Given a parent and a name an object can be located within that parent. The
- locatable object's `__name__` and `__parent__` attributes store this
- information.
-
- Located objects form a hierarchy that can be used to build file-system-like
- structures. For example in Zope `ILocation` is used to build URLs and to
- support security machinery.
-
- To retrieve an object from its parent using its name, the `ISublocation`
- interface provides the `sublocations` method to iterate over all objects
- located within the parent. The object searched for can be found by reading
- each sublocation's __name__ attribute.
-
- """
-
- __parent__ = zope.interface.Attribute("The parent in the location hierarchy.")
-
- __name__ = zope.schema.TextLine(
- title=u"The name within the parent",
- description=u"The object can be looked up from the parent's "
- "sublocations using this name.",
- required=False,
- default=None)
-
-
-class ILocationInfo(zope.interface.Interface):
- """Provides supplemental information for located objects.
-
- Requires that the object has been given a location in a hierarchy.
-
- """
-
- def getRoot():
- """Return the root object of the hierarchy."""
-
- def getPath():
- """Return the physical path to the object as a string.
-
- Uses '/' as the path segment separator.
-
- """
-
- def getName():
- """Return the last segment of the physical path."""
-
- def getNearestSite():
- """Return the site the object is contained in
-
- If the object is a site, the object itself is returned.
-
- """
-
-
-class ISublocations(zope.interface.Interface):
- """Provide access to sublocations of an object.
-
- All objects with the same parent object are called the ``sublocations`` of
- that parent.
-
- """
-
- def sublocations():
- """Return an iterable of the object's sublocations."""
-
-
-class IRoot(zope.interface.Interface):
- """Marker interface to designate root objects within a location hierarchy.
- """
-
-
-
-
-class ITraverser(zope.interface.Interface):
- """Provide traverse features"""
-
- # XXX This is used like a utility but implemented as an adapter: The
- # traversal policy is only implemented once and repeated for all objects
- # along the path.
-
- def traverse(path, default=_RAISE_KEYERROR):
- """Return an object given a path.
-
- Path is either an immutable sequence of strings or a slash ('/')
- delimited string.
-
- If the first string in the path sequence is an empty string, or the
- path begins with a '/', start at the root. Otherwise the path is
- relative to the current context.
-
- If the object is not found, return 'default' argument.
-
- """
-
-
-class LocationError(KeyError, LookupError):
- """There is no object for a given location."""
-
-
-class IPossibleSite(zope.interface.Interface):
- """An object that could be a site.
- """
-
- def setSiteManager(sitemanager):
- """Sets the site manager for this object.
- """
-
- def getSiteManager():
- """Returns the site manager contained in this object.
-
- If there isn't a site manager, raise a component lookup.
- """
-
-
-class ISite(IPossibleSite):
- """Marker interface to indicate that we have a site"""
Copied: zope.location/tags/3.5.1/src/zope/location/interfaces.py (from rev 95958, zope.location/trunk/src/zope/location/interfaces.py)
===================================================================
--- zope.location/tags/3.5.1/src/zope/location/interfaces.py (rev 0)
+++ zope.location/tags/3.5.1/src/zope/location/interfaces.py 2009-02-02 12:16:54 UTC (rev 95961)
@@ -0,0 +1,152 @@
+##############################################################################
+#
+# Copyright (c) 2003-2009 Zope Corporation 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.
+#
+##############################################################################
+"""Location framework interfaces
+
+$Id$
+"""
+__docformat__ = 'restructuredtext'
+
+import zope.interface
+import zope.schema
+
+_RAISE_KEYERROR = object()
+
+
+class ILocation(zope.interface.Interface):
+ """Objects that can be located in a hierachy.
+
+ Given a parent and a name an object can be located within that parent. The
+ locatable object's `__name__` and `__parent__` attributes store this
+ information.
+
+ Located objects form a hierarchy that can be used to build file-system-like
+ structures. For example in Zope `ILocation` is used to build URLs and to
+ support security machinery.
+
+ To retrieve an object from its parent using its name, the `ISublocation`
+ interface provides the `sublocations` method to iterate over all objects
+ located within the parent. The object searched for can be found by reading
+ each sublocation's __name__ attribute.
+
+ """
+
+ __parent__ = zope.interface.Attribute("The parent in the location hierarchy.")
+
+ __name__ = zope.schema.TextLine(
+ title=u"The name within the parent",
+ description=u"The object can be looked up from the parent's "
+ "sublocations using this name.",
+ required=False,
+ default=None)
+
+
+class ILocationInfo(zope.interface.Interface):
+ """Provides supplemental information for located objects.
+
+ Requires that the object has been given a location in a hierarchy.
+
+ """
+
+ def getRoot():
+ """Return the root object of the hierarchy."""
+
+ def getPath():
+ """Return the physical path to the object as a string.
+
+ Uses '/' as the path segment separator.
+
+ """
+
+ def getParents():
+ """Returns a list starting with the object's parent followed by
+ each of its parents.
+
+ Raises a TypeError if the object is not connected to a containment
+ root.
+
+ """
+
+ def getName():
+ """Return the last segment of the physical path."""
+
+ def getNearestSite():
+ """Return the site the object is contained in
+
+ If the object is a site, the object itself is returned.
+
+ """
+
+
+class ISublocations(zope.interface.Interface):
+ """Provide access to sublocations of an object.
+
+ All objects with the same parent object are called the ``sublocations`` of
+ that parent.
+
+ """
+
+ def sublocations():
+ """Return an iterable of the object's sublocations."""
+
+
+class IRoot(zope.interface.Interface):
+ """Marker interface to designate root objects within a location hierarchy.
+ """
+
+
+
+
+class ITraverser(zope.interface.Interface):
+ """Provide traverse features"""
+
+ # XXX This is used like a utility but implemented as an adapter: The
+ # traversal policy is only implemented once and repeated for all objects
+ # along the path.
+
+ def traverse(path, default=_RAISE_KEYERROR):
+ """Return an object given a path.
+
+ Path is either an immutable sequence of strings or a slash ('/')
+ delimited string.
+
+ If the first string in the path sequence is an empty string, or the
+ path begins with a '/', start at the root. Otherwise the path is
+ relative to the current context.
+
+ If the object is not found, return 'default' argument.
+
+ """
+
+
+class LocationError(KeyError, LookupError):
+ """There is no object for a given location."""
+
+
+class IPossibleSite(zope.interface.Interface):
+ """An object that could be a site.
+ """
+
+ def setSiteManager(sitemanager):
+ """Sets the site manager for this object.
+ """
+
+ def getSiteManager():
+ """Returns the site manager contained in this object.
+
+ If there isn't a site manager, raise a component lookup.
+ """
+
+
+class ISite(IPossibleSite):
+ """Marker interface to indicate that we have a site"""
Deleted: zope.location/tags/3.5.1/src/zope/location/location.txt
===================================================================
--- zope.location/trunk/src/zope/location/location.txt 2009-02-02 06:01:56 UTC (rev 95956)
+++ zope.location/tags/3.5.1/src/zope/location/location.txt 2009-02-02 12:16:54 UTC (rev 95961)
@@ -1,153 +0,0 @@
-========
-Location
-========
-
-Location Base Class
--------------------
-
-The `Location` base class is a stupid mix-in that defines `__parent__` and
-`__name__` attributes.
-
-Usage within an Object field:
-
->>> from zope.interface import implements, Interface
->>> from zope.schema import Object
->>> from zope.schema.fieldproperty import FieldProperty
->>> from zope.location.interfaces import ILocation
->>> from zope.location.location import Location
-
->>> class IA(Interface):
-... location = Object(schema=ILocation, required=False, default=None)
->>> class A(object):
-... implements(IA)
-... location = FieldProperty(IA['location'])
-
->>> a = A()
->>> a.location = Location()
-
->>> loc = Location(); loc.__name__ = u'foo'
->>> a.location = loc
-
->>> loc = Location(); loc.__name__ = None
->>> a.location = loc
-
->>> loc = Location(); loc.__name__ = 'foo'
->>> a.location = loc
-Traceback (most recent call last):
-...
-WrongContainedType: [WrongType('foo', <type 'unicode'>)]
-
-
-The `inside` Function
----------------------
-
-The `inside` function tells if l1 is inside l2. L1 is inside l2 if l2 is an
-ancestor of l1.
-
->>> o1 = Location()
->>> o2 = Location(); o2.__parent__ = o1
->>> o3 = Location(); o3.__parent__ = o2
->>> o4 = Location(); o4.__parent__ = o3
-
->>> from zope.location.location import inside
->>> inside(o1, o1)
-1
->>> inside(o2, o1)
-1
->>> inside(o3, o1)
-1
->>> inside(o4, o1)
-1
-
->>> inside(o1, o4)
-0
-
->>> inside(o1, None)
-0
-
-
-LocationProxy
--------------
-
-The LocationProxy is a non-picklable proxy that can be put around
-objects that don't implement `ILocation`.
-
->>> from zope.location.location import LocationProxy
->>> l = [1, 2, 3]
->>> ILocation.providedBy(l)
-False
->>> p = LocationProxy(l, "Dad", "p")
->>> p
-[1, 2, 3]
->>> ILocation.providedBy(p)
-True
->>> p.__parent__
-'Dad'
->>> p.__name__
-'p'
-
->>> import pickle
->>> p2 = pickle.dumps(p)
-Traceback (most recent call last):
-...
-TypeError: Not picklable
-
-Proxies should get their doc strings from the object they proxy:
-
->>> p.__doc__ == l.__doc__
-True
-
-
-The `located` function
-----------------------
-
-`located` locates an object in another and returns it:
-
->>> from zope.location.location import located
->>> a = Location()
->>> parent = Location()
->>> a_located = located(a, parent, 'a')
->>> a_located is a
-True
->>> a_located.__parent__ is parent
-True
->>> a_located.__name__
-'a'
-
-If we locate the object again, nothing special happens:
-
->>> a_located_2 = located(a_located, parent, 'a')
->>> a_located_2 is a_located
-True
-
-
-If the object does not provide ILocation an adapter can be provided:
-
->>> import zope.interface
->>> import zope.component
->>> sm = zope.component.getGlobalSiteManager()
->>> sm.registerAdapter(LocationProxy, required=(zope.interface.Interface,))
-
->>> l = [1, 2, 3]
->>> parent = Location()
->>> l_located = located(l, parent, 'l')
->>> l_located.__parent__ is parent
-True
->>> l_located.__name__
-'l'
->>> l_located is l
-False
->>> type(l_located)
-<class 'zope.location.location.LocationProxy'>
->>> l_located_2 = located(l_located, parent, 'l')
->>> l_located_2 is l_located
-True
-
-When changing the name, we still do not get a different proxied object:
-
->>> l_located_3 = located(l_located, parent, 'new-name')
->>> l_located_3 is l_located_2
-True
-
->>> sm.unregisterAdapter(LocationProxy, required=(zope.interface.Interface,))
-True
Copied: zope.location/tags/3.5.1/src/zope/location/location.txt (from rev 95958, zope.location/trunk/src/zope/location/location.txt)
===================================================================
--- zope.location/tags/3.5.1/src/zope/location/location.txt (rev 0)
+++ zope.location/tags/3.5.1/src/zope/location/location.txt 2009-02-02 12:16:54 UTC (rev 95961)
@@ -0,0 +1,191 @@
+========
+Location
+========
+
+Location Base Class
+-------------------
+
+The `Location` base class is a stupid mix-in that defines `__parent__` and
+`__name__` attributes.
+
+Usage within an Object field:
+
+ >>> from zope.interface import implements, Interface
+ >>> from zope.schema import Object
+ >>> from zope.schema.fieldproperty import FieldProperty
+ >>> from zope.location.interfaces import ILocation
+ >>> from zope.location.location import Location
+
+ >>> class IA(Interface):
+ ... location = Object(schema=ILocation, required=False, default=None)
+ >>> class A(object):
+ ... implements(IA)
+ ... location = FieldProperty(IA['location'])
+
+ >>> a = A()
+ >>> a.location = Location()
+
+ >>> loc = Location(); loc.__name__ = u'foo'
+ >>> a.location = loc
+
+ >>> loc = Location(); loc.__name__ = None
+ >>> a.location = loc
+
+ >>> loc = Location(); loc.__name__ = 'foo'
+ >>> a.location = loc
+ Traceback (most recent call last):
+ ...
+ WrongContainedType: [WrongType('foo', <type 'unicode'>)]
+
+
+The `inside` Function
+---------------------
+
+The `inside` function tells if l1 is inside l2. L1 is inside l2 if l2 is an
+ancestor of l1.
+
+ >>> o1 = Location()
+ >>> o2 = Location(); o2.__parent__ = o1
+ >>> o3 = Location(); o3.__parent__ = o2
+ >>> o4 = Location(); o4.__parent__ = o3
+
+ >>> from zope.location.location import inside
+
+ >>> inside(o1, o1)
+ True
+
+ >>> inside(o2, o1)
+ True
+
+ >>> inside(o3, o1)
+ True
+
+ >>> inside(o4, o1)
+ True
+
+ >>> inside(o1, o4)
+ False
+
+ >>> inside(o1, None)
+ False
+
+
+LocationProxy
+-------------
+
+The LocationProxy is a non-picklable proxy that can be put around
+objects that don't implement `ILocation`.
+
+ >>> from zope.location.location import LocationProxy
+ >>> l = [1, 2, 3]
+ >>> ILocation.providedBy(l)
+ False
+ >>> p = LocationProxy(l, "Dad", "p")
+ >>> p
+ [1, 2, 3]
+ >>> ILocation.providedBy(p)
+ True
+ >>> p.__parent__
+ 'Dad'
+ >>> p.__name__
+ 'p'
+
+ >>> import pickle
+ >>> p2 = pickle.dumps(p)
+ Traceback (most recent call last):
+ ...
+ TypeError: Not picklable
+
+Proxies should get their doc strings from the object they proxy:
+
+ >>> p.__doc__ == l.__doc__
+ True
+
+If we get a "located class" somehow, its doc string well be available
+through proxy as well:
+
+ >>> class LocalClass(object):
+ ... """This is class that can be located"""
+
+ >>> p = LocationProxy(LocalClass)
+ >>> p.__doc__ == LocalClass.__doc__
+ True
+
+LocationInterator
+-----------------
+
+This function allows us to iterate over object and all its parents.
+
+ >>> from zope.location.location import LocationIterator
+
+ >>> o1 = Location()
+ >>> o2 = Location()
+ >>> o3 = Location()
+ >>> o3.__parent__ = o2
+ >>> o2.__parent__ = o1
+
+ >>> iter = LocationIterator(o3)
+ >>> iter.next() is o3
+ True
+ >>> iter.next() is o2
+ True
+ >>> iter.next() is o1
+ True
+ >>> iter.next()
+ Traceback (most recent call last):
+ ...
+ StopIteration
+
+
+The `located` function
+----------------------
+
+`located` locates an object in another and returns it:
+
+ >>> from zope.location.location import located
+ >>> a = Location()
+ >>> parent = Location()
+ >>> a_located = located(a, parent, 'a')
+ >>> a_located is a
+ True
+ >>> a_located.__parent__ is parent
+ True
+ >>> a_located.__name__
+ 'a'
+
+If we locate the object again, nothing special happens:
+
+ >>> a_located_2 = located(a_located, parent, 'a')
+ >>> a_located_2 is a_located
+ True
+
+If the object does not provide ILocation an adapter can be provided:
+
+ >>> import zope.interface
+ >>> import zope.component
+ >>> sm = zope.component.getGlobalSiteManager()
+ >>> sm.registerAdapter(LocationProxy, required=(zope.interface.Interface,))
+
+ >>> l = [1, 2, 3]
+ >>> parent = Location()
+ >>> l_located = located(l, parent, 'l')
+ >>> l_located.__parent__ is parent
+ True
+ >>> l_located.__name__
+ 'l'
+ >>> l_located is l
+ False
+ >>> type(l_located)
+ <class 'zope.location.location.LocationProxy'>
+ >>> l_located_2 = located(l_located, parent, 'l')
+ >>> l_located_2 is l_located
+ True
+
+When changing the name, we still do not get a different proxied object:
+
+ >>> l_located_3 = located(l_located, parent, 'new-name')
+ >>> l_located_3 is l_located_2
+ True
+
+ >>> sm.unregisterAdapter(LocationProxy, required=(zope.interface.Interface,))
+ True
Deleted: zope.location/tags/3.5.1/src/zope/location/pickling.py
===================================================================
--- zope.location/trunk/src/zope/location/pickling.py 2009-02-02 06:01:56 UTC (rev 95956)
+++ zope.location/tags/3.5.1/src/zope/location/pickling.py 2009-02-02 12:16:54 UTC (rev 95961)
@@ -1,238 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2003-2009 Zope Corporation 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.
-#
-##############################################################################
-"""Location copying/pickling support
-
-$Id$
-"""
-__docformat__ = 'restructuredtext'
-
-import cPickle
-import tempfile
-import zope.interface
-import zope.location.interfaces
-
-from zope.location.interfaces import ILocation
-from zope.location.location import Location, inside
-from zope.location.traversing import LocationPhysicallyLocatable
-
-def locationCopy(loc):
- r"""Return a copy of an object, and anything in it
-
- If object in the location refer to objects outside of the
- location, then the copies of the objects in the location refer to
- the same outside objects.
-
- For example, suppose we have an object (location) hierarchy like this::
-
- o1
- / \
- o2 o3
- | |
- o4 o5
-
- >>> o1 = Location()
- >>> o1.o2 = Location(); o1.o2.__parent__ = o1
- >>> o1.o3 = Location(); o1.o3.__parent__ = o1
- >>> o1.o2.o4 = Location(); o1.o2.o4.__parent__ = o1.o2
- >>> o1.o3.o5 = Location(); o1.o3.o5.__parent__ = o1.o3
-
- In addition, o3 has a non-location reference to o4.
-
- >>> o1.o3.o4 = o1.o2.o4
-
- When we copy o3, we should get a copy of o3 and o5, with
- references to o1 and o4.
-
- >>> c3 = locationCopy(o1.o3)
- >>> c3 is o1.o3
- 0
- >>> c3.__parent__ is o1
- 1
- >>> c3.o5 is o1.o3.o5
- 0
- >>> c3.o5.__parent__ is c3
- 1
- >>> c3.o4 is o1.o2.o4
- 1
-
- """
- tmp = tempfile.TemporaryFile()
- persistent = CopyPersistent(loc)
-
- # Pickle the object to a temporary file
- pickler = cPickle.Pickler(tmp, 2)
- pickler.persistent_id = persistent.id
- pickler.dump(loc)
-
- # Now load it back
- tmp.seek(0)
- unpickler = cPickle.Unpickler(tmp)
- unpickler.persistent_load = persistent.load
-
- return unpickler.load()
-
-
-class CopyPersistent(object):
- """Persistence hooks for copying locations
-
- See `locationCopy` above.
-
- We get initialized with an initial location:
-
- >>> o1 = Location()
- >>> persistent = CopyPersistent(o1)
-
- We provide an `id` function that returns None when given a non-location:
-
- >>> persistent.id(42)
-
- Or when given a location that is inside the initial location:
-
- >>> persistent.id(o1)
- >>> o2 = Location(); o2.__parent__ = o1
- >>> persistent.id(o2)
-
- But, if we get a location outside the original location, we assign
- it an `id` and return the `id`:
-
- >>> o3 = Location()
- >>> id3 = persistent.id(o3)
- >>> id3 is None
- 0
- >>> o4 = Location()
- >>> id4 = persistent.id(o4)
- >>> id4 is None
- 0
- >>> id4 is id3
- 0
-
- If we ask for the `id` of an outside location more than once, we
- always get the same `id` back:
-
- >> persistent.id(o4) == id4
- 1
-
- We also provide a load function that returns the objects for which
- we were given ids:
-
- >>> persistent.load(id3) is o3
- 1
- >>> persistent.load(id4) is o4
- 1
-
- """
-
- def __init__(self, location):
- self.location = location
- self.pids_by_id = {}
- self.others_by_pid = {}
- self.load = self.others_by_pid.get
-
- def id(self, object):
- if ILocation.providedBy(object):
- if not inside(object, self.location):
- if id(object) in self.pids_by_id:
- return self.pids_by_id[id(object)]
- pid = len(self.others_by_pid)
-
- # The following is needed to overcome a bug
- # in pickle.py. The pickle checks the boolean value
- # of the id, rather than whether it is None.
- pid += 1
-
- self.pids_by_id[id(object)] = pid
- self.others_by_pid[pid] = object
- return pid
-
- return None
-
-
-class PathPersistent(object):
- """Persistence hooks for pickling locations
-
- See `locationCopy` above.
-
- Unlike copy persistent, we use paths for ids of outside locations
- so that we can separate pickling and unpickling in time. We have
- to compute paths and traverse objects to load paths, but paths can
- be stored for later use, unlike the ids used by `CopyPersistent`.
-
- We require outside locations that can be adapted to `ITraversable`.
- To simplify the example, we'll use a simple traversable location
- defined in `zope.location.tests`, `TLocation`.
-
- Normally, general adapters are used to make objects traversable.
-
- We get initialized with an initial location:
-
- >>> o1 = Location()
- >>> persistent = PathPersistent(o1)
-
- We provide an id function that returns None when given a non-location:
-
- >>> persistent.id(42)
-
- Or when given a location that is inside the initial location:
-
- >>> persistent.id(o1)
- >>> o2 = Location(); o2.__parent__ = o1
- >>> persistent.id(o2)
-
- But, if we get a location outside the original location, we return it's
- path. To compute it's path, it must be rooted:
-
- >>> from zope.location.tests import TLocation
- >>> root = TLocation()
- >>> zope.interface.directlyProvides(
- ... root, zope.location.interfaces.IRoot)
- >>> o3 = TLocation()
- >>> o3.__name__ = 'o3'
- >>> o3.__parent__ = root
- >>> root.o3 = o3
- >>> persistent.id(o3)
- u'/o3'
-
- >>> o4 = TLocation()
- >>> o4.__name__ = 'o4'
- >>> o4.__parent__ = o3
- >>> o3.o4 = o4
- >>> persistent.id(o4)
- u'/o3/o4'
-
- We also provide a load function that returns objects by traversing
- given paths. It has to find the root based on the object given to
- the constructor. Therefore, that object must also be rooted:
-
- >>> o1.__parent__ = root
- >>> persistent.load(u'/o3') is o3
- 1
- >>> persistent.load(u'/o3/o4') is o4
- 1
-
- """
-
- def __init__(self, location):
- self.location = location
-
- def id(self, object):
- if ILocation.providedBy(object):
- if not inside(object, self.location):
- return LocationPhysicallyLocatable(object).getPath()
- return None
-
- def load(self, path):
- if path[:1] != u'/':
- raise ValueError("ZPersistent paths must be absolute", path)
- root = LocationPhysicallyLocatable(self.location).getRoot()
- return zope.location.interfaces.ITraverser(root).traverse(path[1:])
Copied: zope.location/tags/3.5.1/src/zope/location/pickling.py (from rev 95958, zope.location/trunk/src/zope/location/pickling.py)
===================================================================
--- zope.location/tags/3.5.1/src/zope/location/pickling.py (rev 0)
+++ zope.location/tags/3.5.1/src/zope/location/pickling.py 2009-02-02 12:16:54 UTC (rev 95961)
@@ -0,0 +1,245 @@
+##############################################################################
+#
+# Copyright (c) 2003-2009 Zope Corporation 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.
+#
+##############################################################################
+"""Location copying/pickling support
+
+$Id$
+"""
+__docformat__ = 'restructuredtext'
+
+import cPickle
+import tempfile
+import zope.interface
+import zope.location.interfaces
+
+from zope.location.interfaces import ILocation
+from zope.location.location import Location, inside
+from zope.location.traversing import LocationPhysicallyLocatable
+
+def locationCopy(loc):
+ r"""Return a copy of an object, and anything in it
+
+ If object in the location refer to objects outside of the
+ location, then the copies of the objects in the location refer to
+ the same outside objects.
+
+ For example, suppose we have an object (location) hierarchy like this::
+
+ o1
+ / \
+ o2 o3
+ | |
+ o4 o5
+
+ >>> o1 = Location()
+ >>> o1.o2 = Location(); o1.o2.__parent__ = o1
+ >>> o1.o3 = Location(); o1.o3.__parent__ = o1
+ >>> o1.o2.o4 = Location(); o1.o2.o4.__parent__ = o1.o2
+ >>> o1.o3.o5 = Location(); o1.o3.o5.__parent__ = o1.o3
+
+ In addition, o3 has a non-location reference to o4.
+
+ >>> o1.o3.o4 = o1.o2.o4
+
+ When we copy o3, we should get a copy of o3 and o5, with
+ references to o1 and o4.
+
+ >>> c3 = locationCopy(o1.o3)
+ >>> c3 is o1.o3
+ False
+ >>> c3.__parent__ is o1
+ True
+ >>> c3.o5 is o1.o3.o5
+ False
+ >>> c3.o5.__parent__ is c3
+ True
+ >>> c3.o4 is o1.o2.o4
+ True
+
+ """
+ tmp = tempfile.TemporaryFile()
+ persistent = CopyPersistent(loc)
+
+ # Pickle the object to a temporary file
+ pickler = cPickle.Pickler(tmp, 2)
+ pickler.persistent_id = persistent.id
+ pickler.dump(loc)
+
+ # Now load it back
+ tmp.seek(0)
+ unpickler = cPickle.Unpickler(tmp)
+ unpickler.persistent_load = persistent.load
+
+ return unpickler.load()
+
+
+class CopyPersistent(object):
+ """Persistence hooks for copying locations
+
+ See `locationCopy` above.
+
+ We get initialized with an initial location:
+
+ >>> o1 = Location()
+ >>> persistent = CopyPersistent(o1)
+
+ We provide an `id` function that returns None when given a non-location:
+
+ >>> persistent.id(42)
+
+ Or when given a location that is inside the initial location:
+
+ >>> persistent.id(o1)
+ >>> o2 = Location(); o2.__parent__ = o1
+ >>> persistent.id(o2)
+
+ But, if we get a location outside the original location, we assign
+ it an `id` and return the `id`:
+
+ >>> o3 = Location()
+ >>> id3 = persistent.id(o3)
+ >>> id3 is None
+ False
+ >>> o4 = Location()
+ >>> id4 = persistent.id(o4)
+ >>> id4 is None
+ False
+ >>> id4 is id3
+ False
+
+ If we ask for the `id` of an outside location more than once, we
+ always get the same `id` back:
+
+ >> persistent.id(o4) == id4
+ True
+
+ We also provide a load function that returns the objects for which
+ we were given ids:
+
+ >>> persistent.load(id3) is o3
+ True
+ >>> persistent.load(id4) is o4
+ True
+
+ """
+
+ def __init__(self, location):
+ self.location = location
+ self.pids_by_id = {}
+ self.others_by_pid = {}
+ self.load = self.others_by_pid.get
+
+ def id(self, object):
+ if ILocation.providedBy(object):
+ if not inside(object, self.location):
+ if id(object) in self.pids_by_id:
+ return self.pids_by_id[id(object)]
+ pid = len(self.others_by_pid)
+
+ # The following is needed to overcome a bug
+ # in pickle.py. The pickle checks the boolean value
+ # of the id, rather than whether it is None.
+ pid += 1
+
+ self.pids_by_id[id(object)] = pid
+ self.others_by_pid[pid] = object
+ return pid
+
+ return None
+
+
+class PathPersistent(object):
+ """Persistence hooks for pickling locations
+
+ See `locationCopy` above.
+
+ Unlike copy persistent, we use paths for ids of outside locations
+ so that we can separate pickling and unpickling in time. We have
+ to compute paths and traverse objects to load paths, but paths can
+ be stored for later use, unlike the ids used by `CopyPersistent`.
+
+ We require outside locations that can be adapted to `ITraversable`.
+ To simplify the example, we'll use a simple traversable location
+ defined in `zope.location.tests`, `TLocation`.
+
+ Normally, general adapters are used to make objects traversable.
+
+ We get initialized with an initial location:
+
+ >>> o1 = Location()
+ >>> persistent = PathPersistent(o1)
+
+ We provide an id function that returns None when given a non-location:
+
+ >>> persistent.id(42)
+
+ Or when given a location that is inside the initial location:
+
+ >>> persistent.id(o1)
+ >>> o2 = Location(); o2.__parent__ = o1
+ >>> persistent.id(o2)
+
+ But, if we get a location outside the original location, we return it's
+ path. To compute it's path, it must be rooted:
+
+ >>> from zope.location.tests import TLocation
+ >>> root = TLocation()
+ >>> zope.interface.directlyProvides(
+ ... root, zope.location.interfaces.IRoot)
+ >>> o3 = TLocation()
+ >>> o3.__name__ = 'o3'
+ >>> o3.__parent__ = root
+ >>> root.o3 = o3
+ >>> persistent.id(o3)
+ u'/o3'
+
+ >>> o4 = TLocation()
+ >>> o4.__name__ = 'o4'
+ >>> o4.__parent__ = o3
+ >>> o3.o4 = o4
+ >>> persistent.id(o4)
+ u'/o3/o4'
+
+ We also provide a load method that returns objects by traversing
+ given paths. It has to find the root based on the object given to
+ the constructor. Therefore, that object must also be rooted:
+
+ >>> o1.__parent__ = root
+ >>> persistent.load(u'/o3') is o3
+ True
+ >>> persistent.load(u'/o3/o4') is o4
+ True
+
+ We must provide an absolute path for the load method:
+
+ >>> persistent.load(u'o3')
+ Traceback (most recent call last):
+ ...
+ ValueError: ('Persistent paths must be absolute', u'o3')
+
+ """
+
+ def __init__(self, location):
+ self.location = location
+
+ def id(self, object):
+ if ILocation.providedBy(object):
+ if not inside(object, self.location):
+ return LocationPhysicallyLocatable(object).getPath()
+ return None
+
+ def load(self, path):
+ if not path.startswith(u'/'):
+ raise ValueError("Persistent paths must be absolute", path)
+ root = LocationPhysicallyLocatable(self.location).getRoot()
+ return zope.location.interfaces.ITraverser(root).traverse(path[1:])
Deleted: zope.location/tags/3.5.1/src/zope/location/traversing.py
===================================================================
--- zope.location/trunk/src/zope/location/traversing.py 2009-02-02 06:01:56 UTC (rev 95956)
+++ zope.location/tags/3.5.1/src/zope/location/traversing.py 2009-02-02 12:16:54 UTC (rev 95961)
@@ -1,219 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2003-2009 Zope Corporation 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.
-#
-##############################################################################
-"""Classes to support implenting IContained
-
-$Id$
-"""
-__docformat__ = 'restructuredtext'
-
-import zope.component
-import zope.interface
-from zope.location.interfaces import ILocationInfo
-from zope.location.interfaces import IRoot, ITraverser
-from zope.location.interfaces import ILocation, ISite
-from zope.location.location import Location
-
-
-class LocationPhysicallyLocatable(object):
- """Provide location information for location objects
- """
-
- zope.component.adapts(ILocation)
- zope.interface.implements(ILocationInfo)
-
- def __init__(self, context):
- self.context = context
-
- def getRoot(self):
- """Get the root location for a location.
-
- See ILocationInfo
-
- The root location is a location that contains the given
- location and that implements IContainmentRoot.
-
- >>> root = Location()
- >>> zope.interface.directlyProvides(root, IRoot)
- >>> LocationPhysicallyLocatable(root).getRoot() is root
- 1
-
- >>> o1 = Location(); o1.__parent__ = root
- >>> LocationPhysicallyLocatable(o1).getRoot() is root
- 1
-
- >>> o2 = Location(); o2.__parent__ = o1
- >>> LocationPhysicallyLocatable(o2).getRoot() is root
- 1
-
- We'll get a TypeError if we try to get the location fo a
- rootless object:
-
- >>> o1.__parent__ = None
- >>> LocationPhysicallyLocatable(o1).getRoot()
- Traceback (most recent call last):
- ...
- TypeError: Not enough context to determine location root
- >>> LocationPhysicallyLocatable(o2).getRoot()
- Traceback (most recent call last):
- ...
- TypeError: Not enough context to determine location root
-
- If we screw up and create a location cycle, it will be caught:
-
- >>> o1.__parent__ = o2
- >>> LocationPhysicallyLocatable(o1).getRoot()
- Traceback (most recent call last):
- ...
- TypeError: Maximum location depth exceeded, """ \
- """probably due to a a location cycle.
- """
- context = self.context
- max = 9999
- while context is not None:
- if IRoot.providedBy(context):
- return context
- context = context.__parent__
- max -= 1
- if max < 1:
- raise TypeError("Maximum location depth exceeded, "
- "probably due to a a location cycle.")
-
- raise TypeError("Not enough context to determine location root")
-
- def getPath(self):
- """Get the path of a location.
-
- See ILocationInfo
-
- This is an "absolute path", rooted at a root object.
-
- >>> root = Location()
- >>> zope.interface.directlyProvides(root, IRoot)
- >>> LocationPhysicallyLocatable(root).getPath()
- u'/'
-
- >>> o1 = Location(); o1.__parent__ = root; o1.__name__ = 'o1'
- >>> LocationPhysicallyLocatable(o1).getPath()
- u'/o1'
-
- >>> o2 = Location(); o2.__parent__ = o1; o2.__name__ = u'o2'
- >>> LocationPhysicallyLocatable(o2).getPath()
- u'/o1/o2'
-
- It is an error to get the path of a rootless location:
-
- >>> o1.__parent__ = None
- >>> LocationPhysicallyLocatable(o1).getPath()
- Traceback (most recent call last):
- ...
- TypeError: Not enough context to determine location root
-
- >>> LocationPhysicallyLocatable(o2).getPath()
- Traceback (most recent call last):
- ...
- TypeError: Not enough context to determine location root
-
- If we screw up and create a location cycle, it will be caught:
-
- >>> o1.__parent__ = o2
- >>> LocationPhysicallyLocatable(o1).getPath()
- Traceback (most recent call last):
- ...
- TypeError: Maximum location depth exceeded, """ \
- """probably due to a a location cycle.
-
- """
-
- path = []
- context = self.context
- max = 9999
- while context is not None:
- if IRoot.providedBy(context):
- if path:
- path.append('')
- path.reverse()
- return u'/'.join(path)
- else:
- return u'/'
- path.append(context.__name__)
- context = context.__parent__
- max -= 1
- if max < 1:
- raise TypeError("Maximum location depth exceeded, "
- "probably due to a a location cycle.")
-
- raise TypeError("Not enough context to determine location root")
-
- def getParents(self):
- """Returns a list starting with the object's parent followed by
- each of its parents.
-
- Raises a TypeError if the object is not connected to a containment
- root.
-
- """
- # XXX Merge this implementation with getPath. This was refactored
- # from zope.traversing.
- if IRoot.providedBy(self.context):
- return []
-
- parents = []
- w = self.context
- while 1:
- w = w.__parent__
- if w is None:
- break
- parents.append(w)
-
- if parents and IRoot.providedBy(parents[-1]):
- return parents
-
- raise TypeError("Not enough context information to get all parents")
-
- def getName(self):
- """Get a location name
-
- See ILocationInfo
-
- >>> o1 = Location(); o1.__name__ = 'o1'
- >>> LocationPhysicallyLocatable(o1).getName()
- 'o1'
-
- """
- return self.context.__name__
-
- def getNearestSite(self):
- """return the nearest site, see ILocationInfo
-
- >>> o1 = Location()
- >>> o1.__name__ = 'o1'
- >>> LocationPhysicallyLocatable(o1).getNearestSite()
- Traceback (most recent call last):
- ...
- TypeError: Not enough context information to get all parents
-
- >>> root = Location()
- >>> zope.interface.directlyProvides(root, IRoot)
- >>> o1 = Location()
- >>> o1.__name__ = 'o1'
- >>> o1.__parent__ = root
- >>> LocationPhysicallyLocatable(o1).getNearestSite() is root
- 1
- """
- if ISite.providedBy(self.context):
- return self.context
- for parent in self.getParents():
- if ISite.providedBy(parent):
- return parent
- return self.getRoot()
Copied: zope.location/tags/3.5.1/src/zope/location/traversing.py (from rev 95958, zope.location/trunk/src/zope/location/traversing.py)
===================================================================
--- zope.location/tags/3.5.1/src/zope/location/traversing.py (rev 0)
+++ zope.location/tags/3.5.1/src/zope/location/traversing.py 2009-02-02 12:16:54 UTC (rev 95961)
@@ -0,0 +1,263 @@
+##############################################################################
+#
+# Copyright (c) 2003-2009 Zope Corporation 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.
+#
+##############################################################################
+"""Classes to support implenting IContained
+
+$Id$
+"""
+__docformat__ = 'restructuredtext'
+
+import zope.component
+import zope.interface
+from zope.location.interfaces import ILocationInfo
+from zope.location.interfaces import IRoot, ITraverser
+from zope.location.interfaces import ILocation, ISite
+from zope.location.location import Location
+
+
+class LocationPhysicallyLocatable(object):
+ """Provide location information for location objects
+
+ >>> from zope.interface.verify import verifyObject
+ >>> info = LocationPhysicallyLocatable(Location())
+ >>> verifyObject(ILocationInfo, info)
+ True
+
+ """
+
+ zope.component.adapts(ILocation)
+ zope.interface.implements(ILocationInfo)
+
+ def __init__(self, context):
+ self.context = context
+
+ def getRoot(self):
+ """Get the root location for a location.
+
+ See ILocationInfo
+
+ The root location is a location that contains the given
+ location and that implements IContainmentRoot.
+
+ >>> root = Location()
+ >>> zope.interface.directlyProvides(root, IRoot)
+ >>> LocationPhysicallyLocatable(root).getRoot() is root
+ True
+
+ >>> o1 = Location(); o1.__parent__ = root
+ >>> LocationPhysicallyLocatable(o1).getRoot() is root
+ True
+
+ >>> o2 = Location(); o2.__parent__ = o1
+ >>> LocationPhysicallyLocatable(o2).getRoot() is root
+ True
+
+ We'll get a TypeError if we try to get the location fo a
+ rootless object:
+
+ >>> o1.__parent__ = None
+ >>> LocationPhysicallyLocatable(o1).getRoot()
+ Traceback (most recent call last):
+ ...
+ TypeError: Not enough context to determine location root
+ >>> LocationPhysicallyLocatable(o2).getRoot()
+ Traceback (most recent call last):
+ ...
+ TypeError: Not enough context to determine location root
+
+ If we screw up and create a location cycle, it will be caught:
+
+ >>> o1.__parent__ = o2
+ >>> LocationPhysicallyLocatable(o1).getRoot()
+ Traceback (most recent call last):
+ ...
+ TypeError: Maximum location depth exceeded, """ \
+ """probably due to a a location cycle.
+ """
+ context = self.context
+ max = 9999
+ while context is not None:
+ if IRoot.providedBy(context):
+ return context
+ context = context.__parent__
+ max -= 1
+ if max < 1:
+ raise TypeError("Maximum location depth exceeded, "
+ "probably due to a a location cycle.")
+
+ raise TypeError("Not enough context to determine location root")
+
+ def getPath(self):
+ """Get the path of a location.
+
+ See ILocationInfo
+
+ This is an "absolute path", rooted at a root object.
+
+ >>> root = Location()
+ >>> zope.interface.directlyProvides(root, IRoot)
+ >>> LocationPhysicallyLocatable(root).getPath()
+ u'/'
+
+ >>> o1 = Location(); o1.__parent__ = root; o1.__name__ = 'o1'
+ >>> LocationPhysicallyLocatable(o1).getPath()
+ u'/o1'
+
+ >>> o2 = Location(); o2.__parent__ = o1; o2.__name__ = u'o2'
+ >>> LocationPhysicallyLocatable(o2).getPath()
+ u'/o1/o2'
+
+ It is an error to get the path of a rootless location:
+
+ >>> o1.__parent__ = None
+ >>> LocationPhysicallyLocatable(o1).getPath()
+ Traceback (most recent call last):
+ ...
+ TypeError: Not enough context to determine location root
+
+ >>> LocationPhysicallyLocatable(o2).getPath()
+ Traceback (most recent call last):
+ ...
+ TypeError: Not enough context to determine location root
+
+ If we screw up and create a location cycle, it will be caught:
+
+ >>> o1.__parent__ = o2
+ >>> LocationPhysicallyLocatable(o1).getPath()
+ Traceback (most recent call last):
+ ...
+ TypeError: Maximum location depth exceeded, """ \
+ """probably due to a a location cycle.
+
+ """
+
+ path = []
+ context = self.context
+ max = 9999
+ while context is not None:
+ if IRoot.providedBy(context):
+ if path:
+ path.append('')
+ path.reverse()
+ return u'/'.join(path)
+ else:
+ return u'/'
+ path.append(context.__name__)
+ context = context.__parent__
+ max -= 1
+ if max < 1:
+ raise TypeError("Maximum location depth exceeded, "
+ "probably due to a a location cycle.")
+
+ raise TypeError("Not enough context to determine location root")
+
+ def getParents(self):
+ """Returns a list starting with the object's parent followed by
+ each of its parents.
+
+ Raises a TypeError if the object is not connected to a containment
+ root.
+
+ >>> root = Location()
+ >>> zope.interface.directlyProvides(root, IRoot)
+ >>> LocationPhysicallyLocatable(root).getParents()
+ []
+
+ >>> o1 = Location()
+ >>> o2 = Location()
+ >>> o1.__parent__ = root
+ >>> o2.__parent__ = o1
+ >>> LocationPhysicallyLocatable(o2).getParents() == [o1, root]
+ True
+
+ If the last parent is not an IRoot object, TypeError will be
+ raised as statet before.
+
+ >>> zope.interface.noLongerProvides(root, IRoot)
+ >>> LocationPhysicallyLocatable(o2).getParents()
+ Traceback (most recent call last):
+ ...
+ TypeError: Not enough context information to get all parents
+
+ """
+ # XXX Merge this implementation with getPath. This was refactored
+ # from zope.traversing.
+ if IRoot.providedBy(self.context):
+ return []
+
+ parents = []
+ w = self.context
+ while 1:
+ w = w.__parent__
+ if w is None:
+ break
+ parents.append(w)
+
+ if parents and IRoot.providedBy(parents[-1]):
+ return parents
+
+ raise TypeError("Not enough context information to get all parents")
+
+ def getName(self):
+ """Get a location name
+
+ See ILocationInfo
+
+ >>> o1 = Location(); o1.__name__ = u'o1'
+ >>> LocationPhysicallyLocatable(o1).getName()
+ u'o1'
+
+ >>> root = Location()
+ >>> zope.interface.directlyProvides(root, IRoot)
+ >>> LocationPhysicallyLocatable(root).getName()
+ u''
+
+ """
+ if IRoot.providedBy(self.context):
+ return u''
+ return self.context.__name__
+
+ def getNearestSite(self):
+ """return the nearest site, see ILocationInfo
+
+ >>> o1 = Location()
+ >>> o1.__name__ = 'o1'
+ >>> LocationPhysicallyLocatable(o1).getNearestSite()
+ Traceback (most recent call last):
+ ...
+ TypeError: Not enough context information to get all parents
+
+ >>> root = Location()
+ >>> zope.interface.directlyProvides(root, IRoot)
+ >>> o1 = Location()
+ >>> o1.__name__ = 'o1'
+ >>> o1.__parent__ = root
+ >>> LocationPhysicallyLocatable(o1).getNearestSite() is root
+ True
+
+ >>> zope.interface.directlyProvides(o1, ISite)
+ >>> LocationPhysicallyLocatable(o1).getNearestSite() is o1
+ True
+
+ >>> o2 = Location()
+ >>> o2.__parent__ = o1
+ >>> LocationPhysicallyLocatable(o2).getNearestSite() is o1
+ True
+
+ """
+ if ISite.providedBy(self.context):
+ return self.context
+ for parent in self.getParents():
+ if ISite.providedBy(parent):
+ return parent
+ return self.getRoot()
More information about the Checkins
mailing list