[Zope3-checkins] CVS: Zope3/src/zope/app - context.py:1.3
Jim Fulton
jim@zope.com
Mon, 2 Jun 2003 07:05:27 -0400
Update of /cvs-repository/Zope3/src/zope/app
In directory cvs.zope.org:/tmp/cvs-serv19766/src/zope/app
Modified Files:
context.py
Log Message:
Moved functionality to:
- Prevent pickling of context wrappers
- Provide integration of wrapper interfaces in interface specs
to a subclass of the basic wrapper class. The subclass is in zope.app,
because it reflects zope-specific policies.
=== Zope3/src/zope/app/context.py 1.2 => 1.3 ===
--- Zope3/src/zope/app/context.py:1.2 Sun Jun 1 13:23:34 2003
+++ Zope3/src/zope/app/context.py Mon Jun 2 07:04:57 2003
@@ -19,23 +19,89 @@
$Id$
"""
-from zope.interface import moduleProvides
-from zope.security.proxy import Proxy, getChecker
-from zope.context.wrapper import getdictcreate
-from zope.context.wrapper import getcontext
-from zope.context.wrapper import Wrapper
-from zope.security.checker import defineChecker, selectChecker, BasicTypes
-from zope.proxy import queryProxy, getProxiedObject
-from zope.app.interfaces.context import IContextWrapper
from pickle import PicklingError
-from zope.proxy import getProxiedObject
-from zope.interface import providedBy
+from zope.app.interfaces.context import IContextWrapper
+from zope.context.wrapper import getcontext
+from zope.context.wrapper import getdictcreate
+from zope.context.wrapper import Wrapper as BaseWrapper
from zope.interface.declarations import getObjectSpecification
from zope.interface.declarations import ObjectSpecification
from zope.interface.declarations import ObjectSpecificationDescriptor
+from zope.interface import moduleProvides, implements, providedBy
+from zope.proxy import queryProxy, getProxiedObject
+from zope.security.checker import defineChecker, selectChecker, BasicTypes
+from zope.security.proxy import Proxy, getChecker
moduleProvides(IContextWrapper)
__all__ = tuple(IContextWrapper)
+
+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(Wrapper):
+ ... implements(I1)
+
+
+ >>> class D2(Wrapper):
+ ... implements(I2)
+
+ >>> class X:
+ ... implements(I3)
+
+ >>> x = X()
+ >>> directlyProvides(x, I4)
+
+ Interfaces of X are ordered with the directly-provided interfaces first
+
+ >>> [interface.__name__ 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.__name__ for interface in list(providedBy(D1(x)))]
+ ['I4', 'I3', 'I1']
+
+ >>> [interface.__name__ for interface in list(providedBy(D2(D1(x))))]
+ ['I4', 'I3', 'I1', 'I2']
+
+ $Id$
+ """
+
+ def __get__(self, inst, cls):
+ 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 Wrapper(BaseWrapper):
+ """Zope-specific context wrapper
+ """
+
+ def __reduce_ex__(self, proto=None):
+ raise PicklingError, "Zope context wrappers cannot be pickled"
+
+ __reduce__ = __reduce_ex__
+
+ __providedBy__ = DecoratorSpecificationDescriptor()
+
def ContextWrapper(_ob, _parent, **kw):