[Zope3-checkins] SVN: Zope3/trunk/src/zope/app/ Restructured the
location package to:
Jim Fulton
jim at zope.com
Fri May 21 11:37:46 EDT 2004
Log message for revision 24850:
Restructured the location package to:
- Fix a circular-import problem
- get rid of a fat __init__.py. Fat __init__.py modules
are a major source of circular imports.
Moved some code into separate submodules. This, unfortunately, changed
lots of imports.
-=-
Modified: Zope3/trunk/src/zope/app/apidoc/classmodule/tests.py
===================================================================
--- Zope3/trunk/src/zope/app/apidoc/classmodule/tests.py 2004-05-21 15:16:48 UTC (rev 24849)
+++ Zope3/trunk/src/zope/app/apidoc/classmodule/tests.py 2004-05-21 15:37:46 UTC (rev 24850)
@@ -27,7 +27,7 @@
from zope.app.traversing.interfaces import IPhysicallyLocatable
from zope.app.traversing.interfaces import IContainmentRoot
from zope.app.traversing.adapters import DefaultTraversable
-from zope.app.location import LocationPhysicallyLocatable
+from zope.app.location.traversing import LocationPhysicallyLocatable
from zope.app.traversing.adapters import RootPhysicallyLocatable
from zope.app.traversing.adapters import Traverser
Modified: Zope3/trunk/src/zope/app/apidoc/ifacemodule/browser.py
===================================================================
--- Zope3/trunk/src/zope/app/apidoc/ifacemodule/browser.py 2004-05-21 15:16:48 UTC (rev 24849)
+++ Zope3/trunk/src/zope/app/apidoc/ifacemodule/browser.py 2004-05-21 15:37:46 UTC (rev 24850)
@@ -333,8 +333,10 @@
>>> adapters = details.getRequiredAdapters()
>>> pprint(adapters)
- [[('factory', 'zope.app.location.LocationPhysicallyLocatable'),
- ('factory_url', 'zope/app/location/LocationPhysicallyLocatable'),
+ [[('factory',
+ 'zope.app.location.traversing.LocationPhysicallyLocatable'),
+ ('factory_url',
+ 'zope/app/location/traversing/LocationPhysicallyLocatable'),
('name', ''),
('provided',
'zope.app.traversing.interfaces.IPhysicallyLocatable'),
Modified: Zope3/trunk/src/zope/app/apidoc/ifacemodule/tests.py
===================================================================
--- Zope3/trunk/src/zope/app/apidoc/ifacemodule/tests.py 2004-05-21 15:16:48 UTC (rev 24849)
+++ Zope3/trunk/src/zope/app/apidoc/ifacemodule/tests.py 2004-05-21 15:37:46 UTC (rev 24850)
@@ -33,7 +33,8 @@
from zope.app.tree.adapters import LocationUniqueId
from zope.app.traversing.interfaces import IPhysicallyLocatable
-from zope.app.location import LocationPhysicallyLocatable, LocationProxy
+from zope.app.location import LocationProxy
+from zope.app.location.traversing import LocationPhysicallyLocatable
from zope.app.apidoc.classmodule import classRegistry
from zope.app.apidoc.ifacemodule import IInterfaceModule, InterfaceModule
Modified: Zope3/trunk/src/zope/app/apidoc/servicemodule/tests.py
===================================================================
--- Zope3/trunk/src/zope/app/apidoc/servicemodule/tests.py 2004-05-21 15:16:48 UTC (rev 24849)
+++ Zope3/trunk/src/zope/app/apidoc/servicemodule/tests.py 2004-05-21 15:37:46 UTC (rev 24850)
@@ -23,7 +23,7 @@
from zope.app.tree.adapters import LocationUniqueId
from zope.app.traversing.interfaces import IPhysicallyLocatable
-from zope.app.location import LocationPhysicallyLocatable
+from zope.app.location.traversing import LocationPhysicallyLocatable
def setUp():
placelesssetup.setUp()
Modified: Zope3/trunk/src/zope/app/apidoc/utilitymodule/tests.py
===================================================================
--- Zope3/trunk/src/zope/app/apidoc/utilitymodule/tests.py 2004-05-21 15:16:48 UTC (rev 24849)
+++ Zope3/trunk/src/zope/app/apidoc/utilitymodule/tests.py 2004-05-21 15:37:46 UTC (rev 24850)
@@ -35,7 +35,7 @@
from zope.app.tree.adapters import LocationUniqueId
from zope.app.traversing.interfaces import IPhysicallyLocatable
-from zope.app.location import LocationPhysicallyLocatable
+from zope.app.location.traversing import LocationPhysicallyLocatable
def setUp():
Modified: Zope3/trunk/src/zope/app/apidoc/zcmlmodule/tests.py
===================================================================
--- Zope3/trunk/src/zope/app/apidoc/zcmlmodule/tests.py 2004-05-21 15:16:48 UTC (rev 24849)
+++ Zope3/trunk/src/zope/app/apidoc/zcmlmodule/tests.py 2004-05-21 15:37:46 UTC (rev 24850)
@@ -24,7 +24,7 @@
from zope.app.tree.adapters import LocationUniqueId
from zope.app.traversing.interfaces import IPhysicallyLocatable
-from zope.app.location import LocationPhysicallyLocatable
+from zope.app.location.traversing import LocationPhysicallyLocatable
from zope.app.apidoc.zcmlmodule import Namespace, Directive
from zope.app.apidoc.zcmlmodule import ZCMLModule
Modified: Zope3/trunk/src/zope/app/copypastemove/__init__.py
===================================================================
--- Zope3/trunk/src/zope/app/copypastemove/__init__.py 2004-05-21 15:16:48 UTC (rev 24849)
+++ Zope3/trunk/src/zope/app/copypastemove/__init__.py 2004-05-21 15:37:46 UTC (rev 24850)
@@ -24,7 +24,7 @@
from zope.app.event.objectevent import ObjectCopiedEvent
from zope.app.copypastemove.interfaces import IObjectMover
from zope.app.copypastemove.interfaces import IObjectCopier
-from zope.app.location import locationCopy
+from zope.app.location.pickling import locationCopy
from zope.app.container.interfaces import INameChooser
from zope.app.container.constraints import checkObject
Modified: Zope3/trunk/src/zope/app/fssync/fspickle.py
===================================================================
--- Zope3/trunk/src/zope/app/fssync/fspickle.py 2004-05-21 15:16:48 UTC (rev 24849)
+++ Zope3/trunk/src/zope/app/fssync/fspickle.py 2004-05-21 15:37:46 UTC (rev 24850)
@@ -25,7 +25,8 @@
loads() function. The name of the outermost object is not stored in
the pickle unless it is stored in the object.
->>> root = location.TLocation()
+>>> from zope.app.location.tests import TLocation
+>>> root = TLocation()
>>> zope.interface.directlyProvides(root, IContainmentRoot)
>>> o1 = DataLocation('o1', root, 12)
>>> o2 = DataLocation('o2', root, 24)
@@ -70,6 +71,8 @@
from zope.app import location
from zope.app import zapi
from zope.app.location.interfaces import ILocation
+from zope.app.location.traversing import LocationPhysicallyLocatable
+from zope.app.location.tests import TLocation
from zope.app.traversing.interfaces import IContainmentRoot
from zope.app.traversing.interfaces import ITraverser
@@ -107,7 +110,7 @@
class ParentPersistentIdGenerator:
"""
- >>> from zope.app.location import TLocation
+ >>> from zope.app.location.tests import TLocation
>>> root = TLocation()
>>> zope.interface.directlyProvides(root, IContainmentRoot)
>>> o1 = TLocation(); o1.__parent__ = root; o1.__name__ = 'o1'
@@ -135,7 +138,7 @@
def __init__(self, top):
self.location = top
self.parent = getattr(top, "__parent__", None)
- self.root = location.LocationPhysicallyLocatable(top).getRoot()
+ self.root = LocationPhysicallyLocatable(top).getRoot()
def id(self, object):
if ILocation.providedBy(object):
@@ -145,7 +148,7 @@
# XXX emit special parent marker
return PARENT_MARKER
elif location.inside(object, self.root):
- return location.LocationPhysicallyLocatable(object).getPath()
+ return LocationPhysicallyLocatable(object).getPath()
raise ValueError(
"object implementing ILocation found outside tree")
else:
@@ -155,7 +158,7 @@
class PersistentLoader:
def __init__(self, context):
- locatable = location.LocationPhysicallyLocatable(context)
+ locatable = LocationPhysicallyLocatable(context)
__traceback_info__ = (context, locatable),
self.root = locatable.getRoot()
self.traverse = ITraverser(self.root).traverse
@@ -183,7 +186,7 @@
return PersistentLoader.load(self, path)
-class DataLocation(location.TLocation):
+class DataLocation(TLocation):
"""Sample data container class used in doctests."""
def __init__(self, name, parent, data):
Modified: Zope3/trunk/src/zope/app/fssync/tests/test_fspickle.py
===================================================================
--- Zope3/trunk/src/zope/app/fssync/tests/test_fspickle.py 2004-05-21 15:16:48 UTC (rev 24849)
+++ Zope3/trunk/src/zope/app/fssync/tests/test_fspickle.py 2004-05-21 15:37:46 UTC (rev 24850)
@@ -18,7 +18,7 @@
import unittest
from zope.app.traversing.interfaces import IContainmentRoot
-from zope.app.location import TLocation
+from zope.app.location.tests import TLocation
from zope.app.fssync import fspickle
from zope.interface import directlyProvides
Modified: Zope3/trunk/src/zope/app/location/__init__.py
===================================================================
--- Zope3/trunk/src/zope/app/location/__init__.py 2004-05-21 15:16:48 UTC (rev 24849)
+++ Zope3/trunk/src/zope/app/location/__init__.py 2004-05-21 15:37:46 UTC (rev 24850)
@@ -11,516 +11,11 @@
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
-"""Classes to support implenting IContained
+"""Locations
$Id$
"""
-import zope.interface
-from zope.app.location.interfaces import ILocation
-from zope.app.traversing.interfaces import IPhysicallyLocatable
-from zope.app.traversing.interfaces import IContainmentRoot
-from zope.app.traversing.interfaces import ITraverser
-from zope.app.site.interfaces import ISite
-from zope.proxy import removeAllProxies
-from zope.proxy import ProxyBase, getProxiedObject
-from zope.app.decorator import DecoratorSpecificationDescriptor
-from zope.app.decorator import DecoratedSecurityCheckerDescriptor
-from zope.app.traversing import getParents
-import cPickle
-import tempfile
-
-class Location(object):
- """Stupid mix-in that defines __parent__ and __name__ attributes
- """
-
- zope.interface.implements(ILocation)
-
- __parent__ = __name__ = None
-
-def locate(object, parent, name=None):
- """Locate an object in another
-
- This method should only be called from trusted code, because it
- sets attributes that are normally unsettable.
- """
-
- object = removeAllProxies(object)
- object.__parent__ = parent
- object.__name__ = name
-
-
-
-def LocationIterator(object):
- while object is not None:
- yield object
- object = getattr(object, '__parent__', None)
-
-class LocationPhysicallyLocatable:
- """Provide location information for location objects
- """
-
- zope.interface.implements(IPhysicallyLocatable)
-
- def __init__(self, context):
- self.context = context
-
- def getRoot(self):
- """Get the root location for a location.
-
- See IPhysicallyLocatable
-
- The root location is a location that contains the given
- location and that implements IContainmentRoot.
-
- >>> root = Location()
- >>> zope.interface.directlyProvides(root, IContainmentRoot)
- >>> 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: Maximim location depth exceeded, """ \
- """probably due to a a location cycle.
- """
- context = self.context
- max = 9999
- while context is not None:
- if IContainmentRoot.providedBy(context):
- return context
- context = context.__parent__
- max -= 1
- if max < 1:
- raise TypeError("Maximim 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 IPhysicallyLocatable
-
- This is an "absolute path", rooted at a root object.
-
- >>> root = Location()
- >>> zope.interface.directlyProvides(root, IContainmentRoot)
- >>> 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: Maximim location depth exceeded, """ \
- """probably due to a a location cycle.
-
- """
-
- path = []
- context = self.context
- max = 9999
- while context is not None:
- if IContainmentRoot.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("Maximim location depth exceeded, "
- "probably due to a a location cycle.")
-
- raise TypeError("Not enough context to determine location root")
-
- def getName(self):
- """Get a location name
-
- See IPhysicallyLocatable.
-
- >>> o1 = Location(); o1.__name__ = 'o1'
- >>> LocationPhysicallyLocatable(o1).getName()
- 'o1'
-
- """
- return self.context.__name__
-
- def getNearestSite(self):
- """return the nearest site, see IPhysicallyLocatable"""
- if ISite.providedBy(self.context):
- return self.context
- for parent in getParents(self.context):
- if ISite.providedBy(parent):
- return parent
- return self.getRoot()
-
-def inside(l1, l2):
- """Is l1 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
-
- >>> inside(o1, o1)
- 1
- >>> inside(o2, o1)
- 1
- >>> inside(o3, o1)
- 1
- >>> inside(o4, o1)
- 1
-
- >>> inside(o1, o4)
- 0
-
- >>> inside(o1, None)
- 0
-
- """
-
- while l1 is not None:
- if l1 is l2:
- return True
- l1 = l1.__parent__
-
- return False
-
-
-def locationCopy(loc):
- """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-locatin 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, 1) # XXX disable until Python 2.3.4
- 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:
- """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
- # if 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:
- """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.app.location, 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:
-
- >>> root = TLocation()
- >>> zope.interface.directlyProvides(root, IContainmentRoot)
- >>> 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 ITraverser(root).traverse(path[1:])
-
-class ClassAndInstanceDescr(object):
-
- def __init__(self, *args):
- self.funcs = args
-
- def __get__(self, inst, cls):
- if inst is None:
- return self.funcs[1](cls)
- return self.funcs[0](inst)
-
-class LocationProxy(ProxyBase):
- __doc__ = """Location-object proxy
-
- This is a non-picklable proxy that can be put around objects that
- don't implement ILocation.
-
- >>> l = [1, 2, 3]
- >>> p = LocationProxy(l, "Dad", "p")
- >>> p
- [1, 2, 3]
- >>> 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
-
- """
-
- zope.interface.implements(ILocation)
-
- __slots__ = '__parent__', '__name__'
- __safe_for_unpickling__ = True
-
- def __new__(self, ob, container=None, name=None):
- return ProxyBase.__new__(self, ob)
-
- def __init__(self, ob, container=None, name=None):
- ProxyBase.__init__(self, ob)
- self.__parent__ = container
- self.__name__ = name
-
- def __reduce__(self, proto=None):
- raise TypeError, "Not picklable"
-
-
- __doc__ = ClassAndInstanceDescr(
- lambda inst: getProxiedObject(inst).__doc__,
- lambda cls, __doc__ = __doc__: __doc__,
- )
-
- __reduce_ex__ = __reduce__
-
- __providedBy__ = DecoratorSpecificationDescriptor()
-
- __Security_checker__ = DecoratedSecurityCheckerDescriptor()
-
-
-class TLocation(Location):
- """Simple traversable location used in examples."""
-
- zope.interface.implements(ITraverser)
-
- def traverse(self, path, default=None, request=None):
- o = self
- for name in path.split(u'/'):
- o = getattr(o, name)
- return o
+from zope.app.location.location import Location, locate, LocationIterator
+from zope.app.location.location import inside, LocationProxy
+from zope.app.location.interfaces import ILocation
Modified: Zope3/trunk/src/zope/app/location/configure.zcml
===================================================================
--- Zope3/trunk/src/zope/app/location/configure.zcml 2004-05-21 15:16:48 UTC (rev 24849)
+++ Zope3/trunk/src/zope/app/location/configure.zcml 2004-05-21 15:37:46 UTC (rev 24850)
@@ -6,7 +6,7 @@
<adapter
for="zope.app.location.interfaces.ILocation"
provides="zope.app.traversing.interfaces.IPhysicallyLocatable"
- factory="zope.app.location.LocationPhysicallyLocatable"
+ factory="zope.app.location.traversing.LocationPhysicallyLocatable"
/>
</configure>
Copied: Zope3/trunk/src/zope/app/location/location.py (from rev 24847, Zope3/trunk/src/zope/app/location/__init__.py)
===================================================================
--- Zope3/trunk/src/zope/app/location/__init__.py 2004-05-21 13:35:06 UTC (rev 24847)
+++ Zope3/trunk/src/zope/app/location/location.py 2004-05-21 15:37:46 UTC (rev 24850)
@@ -0,0 +1,147 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (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 support
+
+$Id$
+"""
+import zope.interface
+from zope.app.location.interfaces import ILocation
+from zope.proxy import removeAllProxies
+from zope.proxy import ProxyBase, getProxiedObject
+from zope.app.decorator import DecoratorSpecificationDescriptor
+from zope.app.decorator import DecoratedSecurityCheckerDescriptor
+
+class Location(object):
+ """Stupid mix-in that defines __parent__ and __name__ attributes
+ """
+
+ zope.interface.implements(ILocation)
+
+ __parent__ = __name__ = None
+
+def locate(object, parent, name=None):
+ """Locate an object in another
+
+ This method should only be called from trusted code, because it
+ sets attributes that are normally unsettable.
+ """
+
+ object = removeAllProxies(object)
+ object.__parent__ = parent
+ object.__name__ = name
+
+def LocationIterator(object):
+ while object is not None:
+ yield object
+ object = getattr(object, '__parent__', None)
+
+def inside(l1, l2):
+ """Is l1 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
+
+ >>> inside(o1, o1)
+ 1
+ >>> inside(o2, o1)
+ 1
+ >>> inside(o3, o1)
+ 1
+ >>> inside(o4, o1)
+ 1
+
+ >>> inside(o1, o4)
+ 0
+
+ >>> inside(o1, None)
+ 0
+
+ """
+
+ while l1 is not None:
+ if l1 is l2:
+ return True
+ l1 = l1.__parent__
+
+ return False
+
+class ClassAndInstanceDescr(object):
+
+ def __init__(self, *args):
+ self.funcs = args
+
+ def __get__(self, inst, cls):
+ if inst is None:
+ return self.funcs[1](cls)
+ return self.funcs[0](inst)
+
+class LocationProxy(ProxyBase):
+ __doc__ = """Location-object proxy
+
+ This is a non-picklable proxy that can be put around objects that
+ don't implement ILocation.
+
+ >>> l = [1, 2, 3]
+ >>> p = LocationProxy(l, "Dad", "p")
+ >>> p
+ [1, 2, 3]
+ >>> 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
+
+ """
+
+ zope.interface.implements(ILocation)
+
+ __slots__ = '__parent__', '__name__'
+ __safe_for_unpickling__ = True
+
+ def __new__(self, ob, container=None, name=None):
+ return ProxyBase.__new__(self, ob)
+
+ def __init__(self, ob, container=None, name=None):
+ ProxyBase.__init__(self, ob)
+ self.__parent__ = container
+ self.__name__ = name
+
+ def __reduce__(self, proto=None):
+ raise TypeError, "Not picklable"
+
+
+ __doc__ = ClassAndInstanceDescr(
+ lambda inst: getProxiedObject(inst).__doc__,
+ lambda cls, __doc__ = __doc__: __doc__,
+ )
+
+ __reduce_ex__ = __reduce__
+
+ __providedBy__ = DecoratorSpecificationDescriptor()
+
+ __Security_checker__ = DecoratedSecurityCheckerDescriptor()
Copied: Zope3/trunk/src/zope/app/location/pickling.py (from rev 24847, Zope3/trunk/src/zope/app/location/__init__.py)
===================================================================
--- Zope3/trunk/src/zope/app/location/__init__.py 2004-05-21 13:35:06 UTC (rev 24847)
+++ Zope3/trunk/src/zope/app/location/pickling.py 2004-05-21 15:37:46 UTC (rev 24850)
@@ -0,0 +1,233 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (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$
+"""
+
+from zope.app.location.interfaces import ILocation
+from zope.app.location.location import Location, inside
+from zope.app.location.traversing import LocationPhysicallyLocatable
+from zope.app.traversing.interfaces import IContainmentRoot
+from zope.app.traversing.interfaces import ITraverser
+import cPickle
+import tempfile
+import zope.interface
+
+def locationCopy(loc):
+ """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-locatin 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, 1) # XXX disable until Python 2.3.4
+ 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:
+ """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
+ # if 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:
+ """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.app.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.app.location.tests import TLocation
+ >>> root = TLocation()
+ >>> zope.interface.directlyProvides(root, IContainmentRoot)
+ >>> 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 ITraverser(root).traverse(path[1:])
Modified: Zope3/trunk/src/zope/app/location/tests.py
===================================================================
--- Zope3/trunk/src/zope/app/location/tests.py 2004-05-21 15:16:48 UTC (rev 24849)
+++ Zope3/trunk/src/zope/app/location/tests.py 2004-05-21 15:37:46 UTC (rev 24850)
@@ -17,10 +17,31 @@
"""
import unittest
from zope.testing.doctestunit import DocTestSuite
+from zope.app.location.location import Location
+import zope.interface
+from zope.app.traversing.interfaces import ITraverser
+class TLocation(Location):
+ """Simple traversable location used in examples."""
+ zope.interface.implements(ITraverser)
+
+ def traverse(self, path, default=None, request=None):
+ o = self
+ for name in path.split(u'/'):
+ o = getattr(o, name)
+ return o
+
def test_suite():
- return DocTestSuite('zope.app.location')
+ return unittest.TestSuite((
+ DocTestSuite('zope.app.location.location'),
+ DocTestSuite('zope.app.location.traversing'),
+ DocTestSuite('zope.app.location.pickling'),
+ ))
if __name__ == '__main__':
unittest.main(defaultTest='test_suite')
+
+
+
+
Copied: Zope3/trunk/src/zope/app/location/traversing.py (from rev 24847, Zope3/trunk/src/zope/app/location/__init__.py)
===================================================================
--- Zope3/trunk/src/zope/app/location/__init__.py 2004-05-21 13:35:06 UTC (rev 24847)
+++ Zope3/trunk/src/zope/app/location/traversing.py 2004-05-21 15:37:46 UTC (rev 24850)
@@ -0,0 +1,175 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (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$
+"""
+import zope.interface
+from zope.app.traversing.interfaces import IPhysicallyLocatable
+from zope.app.traversing.interfaces import IContainmentRoot
+from zope.app.traversing.interfaces import ITraverser
+from zope.app.site.interfaces import ISite
+from zope.app.traversing import getParents
+from zope.app.location.location import Location
+
+
+class LocationPhysicallyLocatable:
+ """Provide location information for location objects
+ """
+
+ zope.interface.implements(IPhysicallyLocatable)
+
+ def __init__(self, context):
+ self.context = context
+
+ def getRoot(self):
+ """Get the root location for a location.
+
+ See IPhysicallyLocatable
+
+ The root location is a location that contains the given
+ location and that implements IContainmentRoot.
+
+ >>> root = Location()
+ >>> zope.interface.directlyProvides(root, IContainmentRoot)
+ >>> 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: Maximim location depth exceeded, """ \
+ """probably due to a a location cycle.
+ """
+ context = self.context
+ max = 9999
+ while context is not None:
+ if IContainmentRoot.providedBy(context):
+ return context
+ context = context.__parent__
+ max -= 1
+ if max < 1:
+ raise TypeError("Maximim 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 IPhysicallyLocatable
+
+ This is an "absolute path", rooted at a root object.
+
+ >>> root = Location()
+ >>> zope.interface.directlyProvides(root, IContainmentRoot)
+ >>> 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: Maximim location depth exceeded, """ \
+ """probably due to a a location cycle.
+
+ """
+
+ path = []
+ context = self.context
+ max = 9999
+ while context is not None:
+ if IContainmentRoot.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("Maximim location depth exceeded, "
+ "probably due to a a location cycle.")
+
+ raise TypeError("Not enough context to determine location root")
+
+ def getName(self):
+ """Get a location name
+
+ See IPhysicallyLocatable.
+
+ >>> o1 = Location(); o1.__name__ = 'o1'
+ >>> LocationPhysicallyLocatable(o1).getName()
+ 'o1'
+
+ """
+ return self.context.__name__
+
+ def getNearestSite(self):
+ """return the nearest site, see IPhysicallyLocatable"""
+ if ISite.providedBy(self.context):
+ return self.context
+ for parent in getParents(self.context):
+ if ISite.providedBy(parent):
+ return parent
+ return self.getRoot()
Modified: Zope3/trunk/src/zope/app/onlinehelp/tests/test_helpdirectives.py
===================================================================
--- Zope3/trunk/src/zope/app/onlinehelp/tests/test_helpdirectives.py 2004-05-21 15:16:48 UTC (rev 24849)
+++ Zope3/trunk/src/zope/app/onlinehelp/tests/test_helpdirectives.py 2004-05-21 15:37:46 UTC (rev 24850)
@@ -21,7 +21,7 @@
from zope.app.traversing.interfaces import ITraverser, ITraversable
from zope.app.onlinehelp import tests
from zope.app.onlinehelp import help
-from zope.app.location import LocationPhysicallyLocatable
+from zope.app.location.traversing import LocationPhysicallyLocatable
from zope.app.traversing.adapters import Traverser, DefaultTraversable
from zope.app.tests import ztapi
from zope.app.tests.placelesssetup import PlacelessSetup
Modified: Zope3/trunk/src/zope/app/onlinehelp/tests/test_onlinehelp.py
===================================================================
--- Zope3/trunk/src/zope/app/onlinehelp/tests/test_onlinehelp.py 2004-05-21 15:16:48 UTC (rev 24849)
+++ Zope3/trunk/src/zope/app/onlinehelp/tests/test_onlinehelp.py 2004-05-21 15:37:46 UTC (rev 24850)
@@ -24,7 +24,7 @@
from zope.app.onlinehelp import OnlineHelp, IOnlineHelp
from zope.app.traversing.interfaces import ITraversable, IPhysicallyLocatable
from zope.app.traversing.interfaces import IContainmentRoot, ITraverser
-from zope.app.location import LocationPhysicallyLocatable
+from zope.app.location.traversing import LocationPhysicallyLocatable
from zope.app.traversing.adapters import Traverser, DefaultTraversable
from test_onlinehelptopic import TestOnlineHelpTopic, testdir
Modified: Zope3/trunk/src/zope/app/publication/tests/test_zopepublication.py
===================================================================
--- Zope3/trunk/src/zope/app/publication/tests/test_zopepublication.py 2004-05-21 15:16:48 UTC (rev 24849)
+++ Zope3/trunk/src/zope/app/publication/tests/test_zopepublication.py 2004-05-21 15:37:46 UTC (rev 24850)
@@ -402,7 +402,7 @@
def testTransactionAnnotation(self):
from zope.interface import directlyProvides
- from zope.app.location import LocationPhysicallyLocatable
+ from zope.app.location.traversing import LocationPhysicallyLocatable
from zope.app.location.interfaces import ILocation
from zope.app.traversing.interfaces import IPhysicallyLocatable
from zope.app.traversing.interfaces import IContainmentRoot
Modified: Zope3/trunk/src/zope/app/pythonpage/tests.py
===================================================================
--- Zope3/trunk/src/zope/app/pythonpage/tests.py 2004-05-21 15:16:48 UTC (rev 24849)
+++ Zope3/trunk/src/zope/app/pythonpage/tests.py 2004-05-21 15:37:46 UTC (rev 24850)
@@ -22,7 +22,7 @@
from zope.app.traversing.interfaces import IPhysicallyLocatable
from zope.app.interpreter.interfaces import IInterpreter
from zope.app.interpreter.python import PythonInterpreter
-from zope.app.location import LocationPhysicallyLocatable
+from zope.app.location.traversing import LocationPhysicallyLocatable
from zope.app.tests import placelesssetup, ztapi
from zope.app.traversing.adapters import RootPhysicallyLocatable
from zope.component.servicenames import Utilities
Modified: Zope3/trunk/src/zope/app/tests/setup.py
===================================================================
--- Zope3/trunk/src/zope/app/tests/setup.py 2004-05-21 15:16:48 UTC (rev 24849)
+++ Zope3/trunk/src/zope/app/tests/setup.py 2004-05-21 15:37:46 UTC (rev 24850)
@@ -49,7 +49,7 @@
from zope.app.traversing.interfaces import ITraverser, ITraversable
from zope.app.traversing.adapters import DefaultTraversable
from zope.app.traversing.adapters import Traverser, RootPhysicallyLocatable
-from zope.app.location import LocationPhysicallyLocatable
+from zope.app.location.traversing import LocationPhysicallyLocatable
from zope.app.traversing.namespace import etc
def setUpTraversal():
Modified: Zope3/trunk/src/zope/app/traversing/tests/test_conveniencefunctions.py
===================================================================
--- Zope3/trunk/src/zope/app/traversing/tests/test_conveniencefunctions.py 2004-05-21 15:16:48 UTC (rev 24849)
+++ Zope3/trunk/src/zope/app/traversing/tests/test_conveniencefunctions.py 2004-05-21 15:37:46 UTC (rev 24850)
@@ -27,7 +27,7 @@
from zope.app.traversing.interfaces import IPhysicallyLocatable
from zope.app.traversing.interfaces import IContainmentRoot
-from zope.app.location import LocationPhysicallyLocatable
+from zope.app.location.traversing import LocationPhysicallyLocatable
from zope.app.traversing.adapters import RootPhysicallyLocatable
from zope.security.proxy import Proxy
Modified: Zope3/trunk/src/zope/app/traversing/tests/test_physicallocationadapters.py
===================================================================
--- Zope3/trunk/src/zope/app/traversing/tests/test_physicallocationadapters.py 2004-05-21 15:16:48 UTC (rev 24849)
+++ Zope3/trunk/src/zope/app/traversing/tests/test_physicallocationadapters.py 2004-05-21 15:37:46 UTC (rev 24850)
@@ -22,7 +22,7 @@
from zope.app.traversing.interfaces import IContainmentRoot
from zope.app.traversing.interfaces import IPhysicallyLocatable
-from zope.app.location import LocationPhysicallyLocatable
+from zope.app.location.traversing import LocationPhysicallyLocatable
from zope.app.traversing.adapters import RootPhysicallyLocatable
from zope.app.container.contained import contained
from zope.component.interfaces import IServiceService
Modified: Zope3/trunk/src/zope/app/traversing/tests/test_traverser.py
===================================================================
--- Zope3/trunk/src/zope/app/traversing/tests/test_traverser.py 2004-05-21 15:16:48 UTC (rev 24849)
+++ Zope3/trunk/src/zope/app/traversing/tests/test_traverser.py 2004-05-21 15:37:46 UTC (rev 24850)
@@ -28,7 +28,7 @@
from zope.app.traversing.interfaces import IPhysicallyLocatable
from zope.app.traversing.interfaces import IContainmentRoot
-from zope.app.location import LocationPhysicallyLocatable
+from zope.app.location.traversing import LocationPhysicallyLocatable
from zope.app.traversing.adapters import RootPhysicallyLocatable
from zope.app.container.contained import contained
Modified: Zope3/trunk/src/zope/app/undo/tests/test_zodbundomanager.py
===================================================================
--- Zope3/trunk/src/zope/app/undo/tests/test_zodbundomanager.py 2004-05-21 15:16:48 UTC (rev 24849)
+++ Zope3/trunk/src/zope/app/undo/tests/test_zodbundomanager.py 2004-05-21 15:37:46 UTC (rev 24850)
@@ -83,7 +83,7 @@
super(Test, self).setUp()
# provide location adapter
- from zope.app.location import LocationPhysicallyLocatable
+ from zope.app.location.traversing import LocationPhysicallyLocatable
from zope.app.location.interfaces import ILocation
from zope.app.traversing.interfaces import IPhysicallyLocatable
ztapi.provideAdapter(ILocation, IPhysicallyLocatable,
Modified: Zope3/trunk/src/zope/app/wiki/tests/test_wikipagehierarchy.py
===================================================================
--- Zope3/trunk/src/zope/app/wiki/tests/test_wikipagehierarchy.py 2004-05-21 15:16:48 UTC (rev 24849)
+++ Zope3/trunk/src/zope/app/wiki/tests/test_wikipagehierarchy.py 2004-05-21 15:37:46 UTC (rev 24850)
@@ -26,7 +26,7 @@
from zope.app.site.tests.placefulsetup import PlacefulSetup
from zope.app.annotation.attribute import AttributeAnnotations
-from zope.app.location import LocationPhysicallyLocatable
+from zope.app.location.traversing import LocationPhysicallyLocatable
from zope.app.wiki.interfaces import IWikiPage, IWikiPageHierarchy
from zope.app.wiki.wikipage import WikiPage, WikiPageHierarchyAdapter
More information about the Zope3-Checkins
mailing list