[Zope3-checkins] CVS: Zope3/src/zope/app - decorator.py:1.2
Jim Fulton
jim at zope.com
Sun Sep 21 13:30:10 EDT 2003
Update of /cvs-repository/Zope3/src/zope/app
In directory cvs.zope.org:/tmp/cvs-serv11844/src/zope/app
Added Files:
decorator.py
Log Message:
Factored the descriptors into a separate module, since
zope.app.context is now gone. These are still used when creating
decorators with zope.proxy.
=== Zope3/src/zope/app/decorator.py 1.1 => 1.2 ===
--- /dev/null Sun Sep 21 13:30:10 2003
+++ Zope3/src/zope/app/decorator.py Sun Sep 21 13:30:10 2003
@@ -0,0 +1,107 @@
+##############################################################################
+#
+# 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$
+"""
+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
+from zope.interface.declarations import ObjectSpecification
+from zope.interface import providedBy
+
+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(object):
+ """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()
+
More information about the Zope3-Checkins
mailing list