[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