[Checkins] SVN: zope.location/trunk/ - Reverse the dependency between zope.location and zope.traversing. This

Christian Theune ct at gocept.com
Thu Jan 29 14:39:11 EST 2009


Log message for revision 95519:
  - Reverse the dependency between zope.location and zope.traversing. This
    also causes the dependency to various other packages go away.
  
  

Changed:
  U   zope.location/trunk/CHANGES.txt
  U   zope.location/trunk/buildout.cfg
  U   zope.location/trunk/setup.py
  D   zope.location/trunk/src/zope/location/DEPENDENCIES.cfg
  U   zope.location/trunk/src/zope/location/__init__.py
  U   zope.location/trunk/src/zope/location/configure.zcml
  U   zope.location/trunk/src/zope/location/interfaces.py
  U   zope.location/trunk/src/zope/location/location.py
  U   zope.location/trunk/src/zope/location/location.txt
  U   zope.location/trunk/src/zope/location/pickling.py
  U   zope.location/trunk/src/zope/location/tests.py
  U   zope.location/trunk/src/zope/location/traversing.py

-=-
Modified: zope.location/trunk/CHANGES.txt
===================================================================
--- zope.location/trunk/CHANGES.txt	2009-01-29 19:16:15 UTC (rev 95518)
+++ zope.location/trunk/CHANGES.txt	2009-01-29 19:39:10 UTC (rev 95519)
@@ -2,6 +2,12 @@
 CHANGES
 =======
 
+3.5.0 (unreleased)
+------------------
+
+- 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)
 ------------------
 

Modified: zope.location/trunk/buildout.cfg
===================================================================
--- zope.location/trunk/buildout.cfg	2009-01-29 19:16:15 UTC (rev 95518)
+++ zope.location/trunk/buildout.cfg	2009-01-29 19:39:10 UTC (rev 95519)
@@ -1,12 +1,15 @@
 [buildout]
-develop = .
-parts = test
+develop = . ../zope.traversing/ ../z3c.recipe.compattest/
+parts = test compat
 versions = versions
 
+[compat]
+recipe = z3c.recipe.compattest
+max_jobs = 3
+
 [test]
 recipe = zc.recipe.testrunner
 eggs = zope.location
 
 [versions]
-zope.traversing = 3.4.0
-zope.app.publisher = 3.4.0
+ZODB3 = 3.8.1

Modified: zope.location/trunk/setup.py
===================================================================
--- zope.location/trunk/setup.py	2009-01-29 19:16:15 UTC (rev 95518)
+++ zope.location/trunk/setup.py	2009-01-29 19:39:10 UTC (rev 95519)
@@ -51,14 +51,11 @@
       packages=find_packages('src'),
       package_dir = {'': 'src'},
       namespace_packages=['zope',],
-      extras_require=dict(
-          test=['zope.app.container']),
       install_requires=['setuptools',
                         'zope.interface',
                         'zope.schema',
+                        'zope.component',
                         'zope.proxy>3.3',
-                        'zope.security',
-                        'zope.traversing',
                         ],
       include_package_data = True,
       zip_safe = False,

Deleted: zope.location/trunk/src/zope/location/DEPENDENCIES.cfg
===================================================================
--- zope.location/trunk/src/zope/location/DEPENDENCIES.cfg	2009-01-29 19:16:15 UTC (rev 95518)
+++ zope.location/trunk/src/zope/location/DEPENDENCIES.cfg	2009-01-29 19:39:10 UTC (rev 95519)
@@ -1,6 +0,0 @@
-zope.component
-zope.interface
-zope.proxy
-zope.schema
-zope.testing
-zope.traversing

Modified: zope.location/trunk/src/zope/location/__init__.py
===================================================================
--- zope.location/trunk/src/zope/location/__init__.py	2009-01-29 19:16:15 UTC (rev 95518)
+++ zope.location/trunk/src/zope/location/__init__.py	2009-01-29 19:39:10 UTC (rev 95519)
@@ -1,6 +1,6 @@
 ##############################################################################
 #
-# Copyright (c) 2003 Zope Corporation and Contributors.
+# Copyright (c) 2003-2009 Zope Corporation and Contributors.
 # All Rights Reserved.
 #
 # This software is subject to the provisions of the Zope Public License,
@@ -17,6 +17,6 @@
 """
 __docformat__ = 'restructuredtext'
 
+from zope.location.interfaces import ILocation
 from zope.location.location import Location, locate, LocationIterator
 from zope.location.location import inside, LocationProxy
-from zope.location.interfaces import ILocation

Modified: zope.location/trunk/src/zope/location/configure.zcml
===================================================================
--- zope.location/trunk/src/zope/location/configure.zcml	2009-01-29 19:16:15 UTC (rev 95518)
+++ zope.location/trunk/src/zope/location/configure.zcml	2009-01-29 19:39:10 UTC (rev 95519)
@@ -1,5 +1,6 @@
 <configure xmlns="http://namespaces.zope.org/zope">
 
-  <adapter factory="zope.location.traversing.LocationPhysicallyLocatable" />
+  <adapter factory=".traversing.LocationPhysicallyLocatable" />
+  <adapter factory=".location.LocationProxy" />
 
 </configure>

Modified: zope.location/trunk/src/zope/location/interfaces.py
===================================================================
--- zope.location/trunk/src/zope/location/interfaces.py	2009-01-29 19:16:15 UTC (rev 95518)
+++ zope.location/trunk/src/zope/location/interfaces.py	2009-01-29 19:39:10 UTC (rev 95519)
@@ -1,6 +1,6 @@
 ##############################################################################
 #
-# Copyright (c) 2003 Zope Corporation and Contributors.
+# Copyright (c) 2003-2009 Zope Corporation and Contributors.
 # All Rights Reserved.
 #
 # This software is subject to the provisions of the Zope Public License,
@@ -17,34 +17,115 @@
 """
 __docformat__ = 'restructuredtext'
 
-from zope.interface import Interface, Attribute
-from zope import schema
+import zope.interface
+import zope.schema
 
+_RAISE_KEYERROR = object()
 
-class ILocation(Interface):
-    """Objects that have a structural location"""
 
-    __parent__ = Attribute("The parent in the location hierarchy")
+class ILocation(zope.interface.Interface):
+    """Objects that can be located in a hierachy.
 
-    __name__ = schema.TextLine(
+    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"Traverse the parent with this name to get the object.",
+        description=u"The object can be looked up from the parent's "
+            "sublocations using this name.",
         required=False,
         default=None)
 
 
-class ISublocations(Interface):
-    """Provide access to sublocations."""
+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 sublocations
+        """Return an iterable of the object's sublocations."""
 
-        An iterable of objects whose __parent__ is the object
-        providing the interface is returned.
+
+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 IPossibleSite(Interface):
-    """An object that could be a site
+
+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):
@@ -57,5 +138,6 @@
         If there isn't a site manager, raise a component lookup.
         """
 
+
 class ISite(IPossibleSite):
     """Marker interface to indicate that we have a site"""

Modified: zope.location/trunk/src/zope/location/location.py
===================================================================
--- zope.location/trunk/src/zope/location/location.py	2009-01-29 19:16:15 UTC (rev 95518)
+++ zope.location/trunk/src/zope/location/location.py	2009-01-29 19:39:10 UTC (rev 95519)
@@ -1,6 +1,6 @@
 ##############################################################################
 #
-# Copyright (c) 2003 Zope Corporation and Contributors.
+# Copyright (c) 2003-2009 Zope Corporation and Contributors.
 # All Rights Reserved.
 #
 # This software is subject to the provisions of the Zope Public License,
@@ -17,66 +17,64 @@
 """
 __docformat__ = 'restructuredtext'
 
-
 import zope.interface
+import zope.component
+
+# XXX import error when doing import zope.location.interfaces :/
 from zope.location.interfaces import ILocation
-from zope.proxy import ProxyBase, getProxiedObject, non_overridable
+from zope.proxy import ProxyBase, non_overridable
 from zope.proxy.decorator import DecoratorSpecificationDescriptor
-from zope.security.decorator import DecoratedSecurityCheckerDescriptor
 
 
 class Location(object):
-    """Stupid mix-in that defines `__parent__` and `__name__` attributes."""
+    """Mix-in that implements ILocation.
 
+    It provides the `__parent__` and `__name__` attributes.
+
+    """
     zope.interface.implements(ILocation)
 
-    __parent__ = __name__ = None
+    __parent__ = None
+    __name__ = None
 
 
-def locate(object, parent, name=None):
-    """Locate an object in another
+def locate(obj, parent, name=None):
+    """Update a location's coordinates."""
+    obj.__parent__ = parent
+    obj.__name__ = name
 
-    This method should only be called from trusted code, because it
-    sets attributes that are normally unsettable.
-    """
 
-    object.__parent__ = parent
-    object.__name__ = name
+def located(obj, parent, name=None):
+    """Ensure and return the location of an object.
 
+    Updates the location's coordinates.
 
-def located(object, parent, name=None):
-    """Locate an object in another and return it.
-
-    If the object does not provide ILocation a LocationProxy is returned.
-
     """
-    if ILocation.providedBy(object):
-        if parent is not object.__parent__ or name != object.__name__:
-            locate(object, parent, name)
-        return object
-    return LocationProxy(object, parent, name)
+    location = zope.location.interfaces.ILocation(obj)
+    locate(location, parent, name)
+    return location
 
 
 def LocationIterator(object):
+    """Iterate over an object and all of its parents."""
     while object is not None:
         yield object
         object = getattr(object, '__parent__', None)
 
 
 def inside(l1, l2):
-    """Is l1 inside l2
+    """Test whether l1 is a successor of l2.
 
-    L1 is inside l2 if l2 is an ancestor of l1.
+    l1 is a successor of l2 if l2 is in the chain of parents of l1 or l2
+    is l1.
 
     """
     while l1 is not None:
         if l1 is l2:
             return True
         l1 = l1.__parent__
-
     return False
 
-
 class ClassAndInstanceDescr(object):
 
     def __init__(self, *args):
@@ -96,6 +94,7 @@
 
     """
 
+    zope.component.adapts(zope.interface.Interface)
     zope.interface.implements(ILocation)
 
     __slots__ = '__parent__', '__name__'
@@ -122,5 +121,3 @@
     __reduce_ex__ = __reduce__
 
     __providedBy__ = DecoratorSpecificationDescriptor()
-
-    __Security_checker__ = DecoratedSecurityCheckerDescriptor()

Modified: zope.location/trunk/src/zope/location/location.txt
===================================================================
--- zope.location/trunk/src/zope/location/location.txt	2009-01-29 19:16:15 UTC (rev 95518)
+++ zope.location/trunk/src/zope/location/location.txt	2009-01-29 19:39:10 UTC (rev 95519)
@@ -69,8 +69,8 @@
 LocationProxy
 -------------
 
-The LocationProxy is a non-picklable proxy that can be put around objects that
-don't implement `ILocation`.
+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]
@@ -121,13 +121,16 @@
 True
 
 
-If the object does not provide ILocation a LocationProxy is returned:
+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
-[1, 2, 3]
 >>> l_located.__parent__ is parent
 True
 >>> l_located.__name__
@@ -145,3 +148,6 @@
 >>> 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

Modified: zope.location/trunk/src/zope/location/pickling.py
===================================================================
--- zope.location/trunk/src/zope/location/pickling.py	2009-01-29 19:16:15 UTC (rev 95518)
+++ zope.location/trunk/src/zope/location/pickling.py	2009-01-29 19:39:10 UTC (rev 95519)
@@ -1,6 +1,6 @@
 ##############################################################################
 #
-# Copyright (c) 2003 Zope Corporation and Contributors.
+# Copyright (c) 2003-2009 Zope Corporation and Contributors.
 # All Rights Reserved.
 #
 # This software is subject to the provisions of the Zope Public License,
@@ -20,8 +20,7 @@
 import cPickle
 import tempfile
 import zope.interface
-from zope.traversing.interfaces import IContainmentRoot
-from zope.traversing.interfaces import ITraverser
+import zope.location.interfaces
 
 from zope.location.interfaces import ILocation
 from zope.location.location import Location, inside
@@ -195,18 +194,22 @@
 
     >>> from zope.location.tests import TLocation
     >>> root = TLocation()
-    >>> zope.interface.directlyProvides(root, IContainmentRoot)
-    >>> o3 = TLocation(); o3.__name__ = 'o3'
-    >>> o3.__parent__ = root; root.o3 = o3
+    >>> 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
+    >>> 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:
@@ -226,11 +229,10 @@
         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 ITraverser(root).traverse(path[1:])
+        return zope.location.interfaces.ITraverser(root).traverse(path[1:])

Modified: zope.location/trunk/src/zope/location/tests.py
===================================================================
--- zope.location/trunk/src/zope/location/tests.py	2009-01-29 19:16:15 UTC (rev 95518)
+++ zope.location/trunk/src/zope/location/tests.py	2009-01-29 19:39:10 UTC (rev 95519)
@@ -1,6 +1,6 @@
 ##############################################################################
 #
-# Copyright (c) 2003 Zope Corporation and Contributors.
+# Copyright (c) 2003-2009 Zope Corporation and Contributors.
 # All Rights Reserved.
 #
 # This software is subject to the provisions of the Zope Public License,
@@ -15,13 +15,15 @@
 
 $Id$
 """
+
 import unittest
 import zope.interface
 import zope.testing.doctest
-from zope.traversing.interfaces import ITraverser
 from zope.testing.doctestunit import DocTestSuite
+from zope.location.interfaces import ITraverser
 from zope.location.location import Location
 
+
 class TLocation(Location):
     """Simple traversable location used in examples."""
 
@@ -33,12 +35,10 @@
            o = getattr(o, name)
         return o
 
+
 def test_suite():
     return unittest.TestSuite((
         zope.testing.doctest.DocFileSuite('location.txt'),
         DocTestSuite('zope.location.traversing'),
         DocTestSuite('zope.location.pickling'),
         ))
-
-if __name__ == '__main__':
-    unittest.main(defaultTest='test_suite')

Modified: zope.location/trunk/src/zope/location/traversing.py
===================================================================
--- zope.location/trunk/src/zope/location/traversing.py	2009-01-29 19:16:15 UTC (rev 95518)
+++ zope.location/trunk/src/zope/location/traversing.py	2009-01-29 19:39:10 UTC (rev 95519)
@@ -1,6 +1,6 @@
 ##############################################################################
 #
-# Copyright (c) 2003 Zope Corporation and Contributors.
+# Copyright (c) 2003-2009 Zope Corporation and Contributors.
 # All Rights Reserved.
 #
 # This software is subject to the provisions of the Zope Public License,
@@ -19,17 +19,18 @@
 
 import zope.component
 import zope.interface
-from zope.traversing.interfaces import IPhysicallyLocatable
-from zope.traversing.interfaces import IContainmentRoot, ITraverser
-from zope.traversing.api import getParents
+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(IPhysicallyLocatable)
+    zope.interface.implements(ILocationInfo)
 
     def __init__(self, context):
         self.context = context
@@ -37,13 +38,13 @@
     def getRoot(self):
         """Get the root location for a location.
 
-        See IPhysicallyLocatable
+        See ILocationInfo
 
         The root location is a location that contains the given
         location and that implements IContainmentRoot.
 
         >>> root = Location()
-        >>> zope.interface.directlyProvides(root, IContainmentRoot)
+        >>> zope.interface.directlyProvides(root, IRoot)
         >>> LocationPhysicallyLocatable(root).getRoot() is root
         1
 
@@ -80,7 +81,7 @@
         context = self.context
         max = 9999
         while context is not None:
-            if IContainmentRoot.providedBy(context):
+            if IRoot.providedBy(context):
                 return context
             context = context.__parent__
             max -= 1
@@ -93,12 +94,12 @@
     def getPath(self):
         """Get the path of a location.
 
-        See IPhysicallyLocatable
+        See ILocationInfo
 
         This is an "absolute path", rooted at a root object.
 
         >>> root = Location()
-        >>> zope.interface.directlyProvides(root, IContainmentRoot)
+        >>> zope.interface.directlyProvides(root, IRoot)
         >>> LocationPhysicallyLocatable(root).getPath()
         u'/'
 
@@ -138,7 +139,7 @@
         context = self.context
         max = 9999
         while context is not None:
-            if IContainmentRoot.providedBy(context):
+            if IRoot.providedBy(context):
                 if path:
                     path.append('')
                     path.reverse()
@@ -154,10 +155,36 @@
 
         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 IPhysicallyLocatable.
+        See ILocationInfo
 
         >>> o1 = Location(); o1.__name__ = 'o1'
         >>> LocationPhysicallyLocatable(o1).getName()
@@ -167,7 +194,7 @@
         return self.context.__name__
 
     def getNearestSite(self):
-        """return the nearest site, see IPhysicallyLocatable
+        """return the nearest site, see ILocationInfo
 
         >>> o1 = Location()
         >>> o1.__name__ = 'o1'
@@ -177,7 +204,7 @@
         TypeError: Not enough context information to get all parents
 
         >>> root = Location()
-        >>> zope.interface.directlyProvides(root, IContainmentRoot)
+        >>> zope.interface.directlyProvides(root, IRoot)
         >>> o1 = Location()
         >>> o1.__name__ = 'o1'
         >>> o1.__parent__ = root
@@ -186,7 +213,7 @@
         """
         if ISite.providedBy(self.context):
             return self.context
-        for parent in getParents(self.context):
+        for parent in self.getParents():
             if ISite.providedBy(parent):
                 return parent
         return self.getRoot()



More information about the Checkins mailing list