[Zope3-checkins] CVS: Zope3/src/zope/app - decorator.py:1.1.2.1
location.py:1.1.2.1 attributeannotations.py:1.6.24.1
configure.zcml:1.35.2.1 copypastemove.py:1.10.24.1
zapi.py:1.10.2.1 context.py:NONE
Jim Fulton
jim at zope.com
Mon Sep 8 15:22:20 EDT 2003
Update of /cvs-repository/Zope3/src/zope/app
In directory cvs.zope.org:/tmp/cvs-serv20092/src/zope/app
Modified Files:
Tag: parentgeddon-branch
attributeannotations.py configure.zcml copypastemove.py
zapi.py
Added Files:
Tag: parentgeddon-branch
decorator.py location.py
Removed Files:
Tag: parentgeddon-branch
context.py
Log Message:
Checking in work in progress on parentgeddon-branch so Fred can help
me to get the tests passing. Specific log entries will be provided
when we merge this into the head.
=== Added File Zope3/src/zope/app/decorator.py ===
##############################################################################
#
# 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.
#
##############################################################################
"""Decorator support
Decorators are proxies that are mostly transparent but that may provide
additional features.
$Id: decorator.py,v 1.1.2.1 2003/09/08 18:21:18 jim Exp $
"""
from zope.proxy import getProxiedObject, ProxyBase
from zope.security.checker import selectChecker, CombinedChecker
from zope.interface.declarations import ObjectSpecificationDescriptor
from zope.interface.declarations import getObjectSpecification
class DecoratorSpecificationDescriptor(ObjectSpecificationDescriptor):
"""Support for interface declarations on decorators
>>> from zope.interface import *
>>> class I1(Interface):
... pass
>>> class I2(Interface):
... pass
>>> class I3(Interface):
... pass
>>> class I4(Interface):
... pass
>>> class D1(Decorator):
... implements(I1)
>>> class D2(Decorator):
... implements(I2)
>>> class X:
... implements(I3)
>>> x = X()
>>> directlyProvides(x, I4)
Interfaces of X are ordered with the directly-provided interfaces first
>>> [interface.getName() for interface in list(providedBy(x))]
['I4', 'I3']
When we decorate objects, what order should the interfaces come
in? One could argue that decorators are less specific, so they
should come last.
>>> [interface.getName() for interface in list(providedBy(D1(x)))]
['I4', 'I3', 'I1']
>>> [interface.getName() for interface in list(providedBy(D2(D1(x))))]
['I4', 'I3', 'I1', 'I2']
"""
def __get__(self, inst, cls=None):
if inst is None:
return getObjectSpecification(cls)
else:
provided = providedBy(getProxiedObject(inst))
# Use type rather than __class__ because inst is a proxy and
# will return the proxied object's class.
cls = type(inst)
return ObjectSpecification(provided, cls)
class DecoratedSecurityCheckerDescriptor:
"""Descriptor for a Decorator that provides a decorated security checker.
"""
def __get__(self, inst, cls=None):
if inst is None:
return self
else:
proxied_object = getProxiedObject(inst)
checker = getattr(proxied_object, '__Security_checker__', None)
if checker is None:
checker = selectChecker(proxied_object)
wrapper_checker = selectChecker(inst)
if wrapper_checker is None:
return checker
elif checker is None:
return wrapper_checker
else:
return CombinedChecker(wrapper_checker, checker)
class Decorator(ProxyBase):
"""Decorator base class
"""
__providedBy__ = DecoratorSpecificationDescriptor()
__Security_checker__ = DecoratedSecurityCheckerDescriptor()
=== Added File Zope3/src/zope/app/location.py ===
##############################################################################
#
# 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: location.py,v 1.1.2.1 2003/09/08 18:21:18 jim Exp $
"""
import zope.interface
from zope.app import zapi
from zope.app.interfaces.location import ILocation
from zope.app.interfaces.traversing import IPhysicallyLocatable
from zope.app.interfaces.traversing import IContainmentRoot
from zope.app.interfaces.traversing import ITraverser
import cPickle
import tempfile
class Location(object):
"""Stupid mix-in that defines __parent__ and __name__ attributes
"""
zope.interface.implements(ILocation)
__parent__ = __name__ = 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.isImplementedBy(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.isImplementedBy(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 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, 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:
"""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
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.others = {}
self.load = self.others.get
def id(self, object):
if ILocation.isImplementedBy(object):
if not inside(object, self.location):
others = self.others
pid = len(others)
others[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 make an traversable location:
>>> class TLocation(Location):
... 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
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.isImplementedBy(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 zapi.getAdapter(root, ITraverser).traverse(path[1:])
=== Zope3/src/zope/app/attributeannotations.py 1.6 => 1.6.24.1 ===
--- Zope3/src/zope/app/attributeannotations.py:1.6 Tue Jun 3 11:33:55 2003
+++ Zope3/src/zope/app/attributeannotations.py Mon Sep 8 14:21:18 2003
@@ -19,8 +19,8 @@
from zodb.btrees.OOBTree import OOBTree
from zope.app.interfaces.annotation import IAnnotations
from zope.proxy import removeAllProxies
-from zope.app.context import ContextWrapper
from zope.interface import implements
+from zope.app.interfaces.location import ILocation
class AttributeAnnotations:
"""
@@ -39,17 +39,28 @@
self.unwrapped_obj = removeAllProxies(obj)
def __getitem__(self, key):
- annotations = getattr(self.unwrapped_obj, '__annotations__', {})
- return ContextWrapper(annotations[key], self.wrapped_obj)
+ annotations = getattr(self.unwrapped_obj, '__annotations__', None)
+ if annotations is None:
+ raise KeyError, key
+ return annotations[key]
+
+ def __setitem__(self, key, value):
+ if ILocation.isImplementedBy(value):
+ value.__parent__ = self.unwrapped_obj
+
+ try:
+ annotations = self.unwrapped_obj.__annotations__
+ except AttributeError:
+ annotations = self.unwrapped_obj.__annotations__ = OOBTree()
+
+ annotations[key] = value
def get(self, key, default=None):
try:
- value = self.unwrapped_obj.__annotations__.get(key, default)
+ return self.unwrapped_obj.__annotations__.get(key, default)
except AttributeError:
# I guess default shouldn't be wrapped.
return default
- else:
- return ContextWrapper(value, self.wrapped_obj)
def __getattr__(self, name):
# this method is for getting methods and attributes of the
@@ -62,4 +73,5 @@
attr = getattr(annotations, name)
else:
raise
- return ContextWrapper(attr, self.wrapped_obj)
+
+ return attr
=== Zope3/src/zope/app/configure.zcml 1.35 => 1.35.2.1 ===
--- Zope3/src/zope/app/configure.zcml:1.35 Tue Sep 2 16:45:32 2003
+++ Zope3/src/zope/app/configure.zcml Mon Sep 8 14:21:18 2003
@@ -87,6 +87,12 @@
provides="zope.app.interfaces.copypastemove.IPrincipalClipboard"
for="zope.app.interfaces.annotation.IAnnotations" />
+ <adapter
+ for=".interfaces.location.ILocation"
+ provides=".interfaces.traversing.IPhysicallyLocatable"
+ factory=".location.LocationPhysicallyLocatable"
+ />
+
<include package="zope.app.container" />
<include package="zope.app.content" />
<include package="zope.app.services" />
=== Zope3/src/zope/app/copypastemove.py 1.10 => 1.10.24.1 ===
--- Zope3/src/zope/app/copypastemove.py:1.10 Fri Jun 13 13:41:10 2003
+++ Zope3/src/zope/app/copypastemove.py Mon Sep 8 14:21:18 2003
@@ -17,8 +17,7 @@
$Id$
"""
-from zope.app.traversing import getParent, getName, getPath
-from zope.component import getAdapter, queryAdapter
+from zope.app import zapi
from zope.app.interfaces.copypastemove import IObjectMover
from zope.app.interfaces.copypastemove import IObjectCopier
from zope.app.interfaces.copypastemove import INoChildrenObjectCopier
@@ -34,6 +33,7 @@
from zope.app.event import publish
from zope.proxy import removeAllProxies
from zope.interface import implements
+from zope.exceptions import NotFoundError, DuplicationError
class ObjectMover:
'''Use getAdapter(obj, IObjectMover) to move an object somewhere.'''
@@ -50,32 +50,33 @@
Typically, the target is adapted to IPasteTarget.'''
obj = self.context
- container = getParent(obj)
- orig_name = getName(obj)
+ container = zapi.getParent(obj)
+ orig_name = zapi.getName(obj)
if new_name is None:
new_name = orig_name
- movesource = getAdapter(container, IMoveSource)
- target_path = getPath(target)
- source_path = getPath(container)
+ movesource = zapi.getAdapter(container, IMoveSource)
+ target_path = zapi.getPath(target)
+ source_path = zapi.getPath(container)
- if queryAdapter(obj, IMoveNotifiable):
- getAdapter(obj, IMoveNotifiable).beforeDeleteHook(
+ if zapi.queryAdapter(obj, IMoveNotifiable):
+ zapi.getAdapter(obj, IMoveNotifiable).beforeDeleteHook(
obj, container, movingTo=target_path)
- elif queryAdapter(obj, IDeleteNotifiable):
- getAdapter(obj, IDeleteNotifiable).beforeDeleteHook(obj, container)
+ elif zapi.queryAdapter(obj, IDeleteNotifiable):
+ zapi.getAdapter(obj, IDeleteNotifiable
+ ).beforeDeleteHook(obj, container)
new_obj = movesource.removeObject(orig_name, target)
- pastetarget = getAdapter(target, IPasteTarget)
+ pastetarget = zapi.getAdapter(target, IPasteTarget)
# publish an ObjectCreatedEvent (perhaps...?)
new_name = pastetarget.pasteObject(new_name, new_obj)
# call afterAddHook
- if queryAdapter(new_obj, IMoveNotifiable):
- getAdapter(new_obj, IMoveNotifiable).afterAddHook(
+ if zapi.queryAdapter(new_obj, IMoveNotifiable):
+ zapi.getAdapter(new_obj, IMoveNotifiable).afterAddHook(
new_obj, container, movedFrom=source_path)
- elif queryAdapter(new_obj, IAddNotifiable):
- getAdapter(new_obj, IAddNotifiable).afterAddHook(
+ elif zapi.queryAdapter(new_obj, IAddNotifiable):
+ zapi.getAdapter(new_obj, IAddNotifiable).afterAddHook(
new_obj, container)
# publish ObjectMovedEvent
@@ -96,8 +97,8 @@
'''
obj = self.context
if name is None:
- name = getName(obj)
- pastetarget = getAdapter(target, IPasteTarget)
+ name = zapi.getName(obj)
+ pastetarget = zapi.getAdapter(target, IPasteTarget)
return pastetarget.acceptsObject(name, obj)
class ObjectCopier:
@@ -119,27 +120,27 @@
an IObjectCreated event should be published.
"""
obj = self.context
- container = getParent(obj)
- orig_name = getName(obj)
+ container = zapi.getParent(obj)
+ orig_name = zapi.getName(obj)
if new_name is None:
new_name = orig_name
- target_path = getPath(target)
- source_path = getPath(container)
+ target_path = zapi.getPath(target)
+ source_path = zapi.getPath(container)
- copysource = getAdapter(container, ICopySource)
+ copysource = zapi.getAdapter(container, ICopySource)
obj = copysource.copyObject(orig_name, target_path)
- pastetarget = getAdapter(target, IPasteTarget)
+ pastetarget = zapi.getAdapter(target, IPasteTarget)
# publish an ObjectCreatedEvent (perhaps...?)
new_name = pastetarget.pasteObject(new_name, obj)
# call afterAddHook
- if queryAdapter(obj, ICopyNotifiable):
- getAdapter(obj, ICopyNotifiable).afterAddHook(
+ if zapi.queryAdapter(obj, ICopyNotifiable):
+ zapi.getAdapter(obj, ICopyNotifiable).afterAddHook(
obj, container, copiedFrom=source_path)
- elif queryAdapter(obj, IAddNotifiable):
- getAdapter(obj, IAddNotifiable).afterAddHook(obj, container)
+ elif zapi.queryAdapter(obj, IAddNotifiable):
+ zapi.getAdapter(obj, IAddNotifiable).afterAddHook(obj, container)
# publish ObjectCopiedEvent
publish(container,
@@ -159,8 +160,8 @@
'''
obj = self.context
if name is None:
- name = getName(obj)
- pastetarget = getAdapter(target, IPasteTarget)
+ name = zapi.getName(obj)
+ pastetarget = zapi.getAdapter(target, IPasteTarget)
return pastetarget.acceptsObject(name, obj)
@@ -183,31 +184,31 @@
an IObjectCreated event should be published.
"""
obj = self.context
- container = getParent(obj)
- orig_name = getName(obj)
+ container = zapi.getParent(obj)
+ orig_name = zapi.getName(obj)
if new_name is None:
new_name = orig_name
- target_path = getPath(target)
- source_path = getPath(container)
+ target_path = zapi.getPath(target)
+ source_path = zapi.getPath(container)
- copysource = getAdapter(container, INoChildrenCopySource)
+ copysource = zapi.getAdapter(container, INoChildrenCopySource)
obj = copysource.copyObjectWithoutChildren(orig_name, target_path)
if obj is None:
raise CopyException(container, orig_name,
'Could not get a copy without children of %s'
% orig_name)
- pastetarget = getAdapter(target, IPasteTarget)
+ pastetarget = zapi.getAdapter(target, IPasteTarget)
# publish an ObjectCreatedEvent (perhaps...?)
new_name = pastetarget.pasteObject(new_name, obj)
# call afterAddHook
- if queryAdapter(obj, ICopyNotifiable):
- getAdapter(obj, ICopyNotifiable).afterAddHook(
+ if zapi.queryAdapter(obj, ICopyNotifiable):
+ zapi.getAdapter(obj, ICopyNotifiable).afterAddHook(
obj, container, copiedFrom=source_path)
- elif queryAdapter(obj, IAddNotifiable):
- getAdapter(obj, IAddNotifiable).afterAddHook(obj, container)
+ elif zapi.queryAdapter(obj, IAddNotifiable):
+ zapi.getAdapter(obj, IAddNotifiable).afterAddHook(obj, container)
# publish ObjectCopiedEvent
publish(container, ObjectCopiedEvent(
@@ -245,3 +246,18 @@
'''Return the contents of the clipboard'''
return removeAllProxies(self.context.get('clipboard', ()))
+
+def rename(container, oldid, newid):
+ object = container.get(oldid)
+ if object is None:
+ raise NotFoundError(self, oldid)
+ mover = zapi.getAdapter(object, IObjectMover)
+
+ if newid in container:
+ raise DuplicationError("name, %s, is already in use" % newid)
+
+ if mover.moveable() and mover.moveableTo(container, newid):
+ # the mover will call beforeDeleteHook hook for us
+ mover.moveTo(container, newid)
+ # the mover will call the afterAddHook hook for us
+ # the mover will publish an ObjectMovedEvent for us
=== Zope3/src/zope/app/zapi.py 1.10 => 1.10.2.1 ===
--- Zope3/src/zope/app/zapi.py:1.10 Wed Sep 3 14:33:54 2003
+++ Zope3/src/zope/app/zapi.py Mon Sep 8 14:21:18 2003
@@ -20,17 +20,18 @@
from zope.app.interfaces.zapi import IZAPI
from zope.interface import moduleProvides
-from zope.context import getWrapperData
moduleProvides(IZAPI)
__all__ = tuple(IZAPI)
from zope.component import *
+
# XXX: 'queryService' is not part of IComponentArchitecture;
# XXX: Jim says you shouldn't need it anyway.
+# YYY: So why is it here?
+
from zope.component import queryService
-from zope.context import *
-from zope.app.context import *
+
from zope.app.traversing import *
from zope.app.interfaces.exceptions import UserError
=== Removed File Zope3/src/zope/app/context.py ===
More information about the Zope3-Checkins
mailing list