[Zodb-checkins] CVS: Zope3/src/zope/interface - declarations.py:1.17.10.7 interface.py:1.13.4.6 interfaces.py:1.15.8.2

Jim Fulton cvs-admin at zope.org
Thu Nov 6 07:35:46 EST 2003


Update of /cvs-repository/Zope3/src/zope/interface
In directory cvs.zope.org:/tmp/cvs-serv30369/src/zope/interface

Modified Files:
      Tag: adaptergeddon-branch
	declarations.py interface.py interfaces.py 
Log Message:
Created some new C optimizations for interfaces.

Small optimization in specification lookup.


=== Zope3/src/zope/interface/declarations.py 1.17.10.6 => 1.17.10.7 ===
--- Zope3/src/zope/interface/declarations.py:1.17.10.6	Thu Oct 16 17:42:38 2003
+++ Zope3/src/zope/interface/declarations.py	Thu Nov  6 07:35:10 2003
@@ -35,6 +35,10 @@
 from types import ClassType
 from zope.interface.advice import addClassAdvisor
 
+# Registry of class-implementation specifications 
+BuiltinImplementationSpecifications = {}
+
+
 __metaclass__ = type
 
 class Declaration(Specification):
@@ -251,14 +255,11 @@
 #
 # These specify interfaces implemented by instances of classes
 
-# Registry of class-implementation specifications 
-BuiltinImplementationSpecifications = {}
-
 class Implements(Declaration):
     inherit = None
     declared = ()
 
-def implementedBy(cls):
+def implementedByFallback(cls):
     """Return the interfaces implemented for a class' instances
 
       The value returned is an IDeclaration.
@@ -294,12 +295,14 @@
 
         # We don't want to depend directly on zope.secury in
         # zope.interface, but we'll try to make reasonable
-        # accomidations in an indirect way.
+        # accommodations in an indirect way.
 
         # We'll check to see if there's an implements:
 
-        spec = getattr(cls, '__implements__', _empty)
-        if isinstance(spec, Implements):
+        spec = getattr(cls, '__implements__', None)
+        if spec is None:
+            return _empty
+        if spec.__class__ == Implements:
             # we defaulted to _empty or there was a spec. Good enough.
             # Return it.
             return spec
@@ -331,6 +334,16 @@
         cls.__implements__ = spec
         if not hasattr(cls, '__providedBy__'):
             cls.__providedBy__ = objectSpecificationDescriptor
+
+        if (isinstance(cls, DescriptorAwareMetaClasses)
+            and
+            '__provides__' not in cls.__dict__):
+            # Make sure we get a __provides__ descriptor
+            cls.__provides__ = ClassProvides(
+                cls,
+                getattr(cls, '__class__', type(cls)),
+                )
+                        
     except TypeError:
         if not isinstance(cls, type):
             raise TypeError("ImplementedBy called for non-type", cls)
@@ -338,6 +351,8 @@
 
     return spec
 
+implementedBy = implementedByFallback
+
 def classImplementsOnly(cls, *interfaces):
     """Declare the only interfaces implemented by instances of a class
 
@@ -442,8 +457,8 @@
     spec.__bases__ = bases
 
 def _implements_advice(cls):
-    interfaces, classImplements = cls.__dict__['__implements__']
-    del cls.__implements__
+    interfaces, classImplements = cls.__dict__['__implements_advice_data__']
+    del cls.__implements_advice_data__
     classImplements(cls, *interfaces)
     return cls
 
@@ -455,10 +470,10 @@
     if (locals is frame.f_globals) or ('__module__' not in locals):
         raise TypeError(name+" can be used only from a class definition.")
 
-    if '__implements__' in locals:
+    if '__implements_advice_data__' in locals:
         raise TypeError(name+" can be used only once in a class definition.")
 
-    locals['__implements__'] = interfaces, classImplements
+    locals['__implements_advice_data__'] = interfaces, classImplements
     addClassAdvisor(_implements_advice, depth=3)
 
 def implements(*interfaces):
@@ -585,7 +600,7 @@
 #
 # Instance declarations
 
-class Provides(Declaration):
+class Provides(Declaration):  # Really named ProvidesClass
     """Implement __provides__, the instance-specific specification
 
     When an object is pickled, we pickle the interfaces that it implements.
@@ -593,6 +608,7 @@
 
     def __init__(self, cls, *interfaces):
         self.__args = (cls, ) + interfaces
+        self._cls = cls
         Declaration.__init__(self, *(interfaces + (implementedBy(cls), )))
 
     def __reduce__(self):
@@ -608,22 +624,22 @@
           >>> from zope.interface import Interface
           >>> class IFooFactory(Interface): pass
           ...
+          
           >>> class C:
-          ...   classProvides(IFooFactory)
+          ...   pass
+
+          >>> C.__provides__ = ProvidesClass(C, IFooFactory)
           >>> [i.getName() for i in C.__provides__]
           ['IFooFactory']
           >>> getattr(C(), '__provides__', 0)
           0
 
         """
-        if inst is None:
+        if inst is None and cls is self._cls:
             # We were accessed through a class, so we are the class'
-            # provides spec. Just return this object as is, but only
-            # if it is in the class dict.
-            r = cls.__dict__.get('__provides__')
-            if r is not None:
-                assert(r is self)
-                return r
+            # provides spec. Just return this object, but only if we are
+            # being called on the same class that we were defined for:
+            return self
 
         raise AttributeError, '__provides__'
 
@@ -779,7 +795,78 @@
     interfaces = _normalizeargs(interfaces)
     if cls is None:
         cls = type(object)
-    object.__provides__ = Provides(cls, *interfaces)
+
+    if issubclass(cls, DescriptorAwareMetaClasses):
+        # we have a class or type.  We'll use a special descriptor
+        # that provides some extra caching
+        object.__provides__ = ClassProvides(object, cls, *interfaces)
+    else:
+        object.__provides__ = Provides(cls, *interfaces)
+
+
+class ClassProvidesBasePy(object):
+
+    def __get__(self, inst, cls):
+        if cls is self._cls:
+            # We only work if called on the class we were defined for
+            
+            if inst is None:
+                # We were accessed through a class, so we are the class'
+                # provides spec. Just return this object as is:
+                return self
+
+            return self._implements
+
+        raise AttributeError, '__provides__'
+
+ClassProvidesBase = ClassProvidesBasePy
+
+# Try to get C base:
+try:
+    import _zope_interface_coptimizations
+except ImportError:
+    pass
+else:
+    from _zope_interface_coptimizations import ClassProvidesBase
+
+
+class ClassProvides(Declaration, ClassProvidesBase):
+    """Special descriptor for class __provides__
+
+    The descriptor caches the implementedBy info, so that
+    we can get declarations for objects without instance-specific
+    interfaces a bit quicker.
+
+        For example::
+
+          >>> from zope.interface import Interface
+          >>> class IFooFactory(Interface):
+          ...     pass
+          >>> class IFoo(Interface):
+          ...     pass
+          >>> class C:
+          ...     implements(IFoo)
+          ...     classProvides(IFooFactory)
+          >>> [i.getName() for i in C.__provides__]
+          ['IFooFactory']
+
+          >>> [i.getName() for i in C().__provides__]
+          ['IFoo']
+
+    
+    """
+
+    def __init__(self, cls, metacls, *interfaces):
+        self._cls = cls
+        self._implements = implementedBy(cls)
+        self.__args = (cls, metacls, ) + interfaces
+        Declaration.__init__(self, *(interfaces + (implementedBy(metacls), )))
+
+    def __reduce__(self):
+        return self.__class__, self.__args
+
+    # Copy base-class method for speed
+    __get__ = ClassProvidesBase.__get__
 
 def directlyProvidedBy(object):
     """Return the interfaces directly provided by the given object
@@ -788,8 +875,16 @@
 
     """
     provides = getattr(object, "__provides__", None)
-    if provides is None:
+    if (provides is None # no spec
+        or
+        # We might have gotten the implements spec, as an
+        # optimization. If so, it's like having only one base, that we
+        # lop off to exclude class-supplied declarations:
+        isinstance(provides, Implements)
+        ):
         return _empty
+
+    # Strip off the class part of the spec:
     return Declaration(provides.__bases__[:-1])
 
 def classProvides(*interfaces):
@@ -1050,7 +1145,7 @@
 
     return r
 
-class ObjectSpecificationDescriptor(object):
+class ObjectSpecificationDescriptorPy(object):
     """Implement the __providedBy__ attribute
 
     The __providedBy__ attribute computes the interfaces peovided by
@@ -1089,6 +1184,8 @@
 
         return implementedBy(cls)
 
+ObjectSpecificationDescriptor = ObjectSpecificationDescriptorPy
+
 objectSpecificationDescriptor = ObjectSpecificationDescriptor()
 
 ##############################################################################
@@ -1114,3 +1211,12 @@
     return output
 
 _empty = Declaration()
+
+try:
+    import _zope_interface_coptimizations
+except ImportError:
+    pass
+else:
+    from _zope_interface_coptimizations import implementedBy, providedBy
+    from _zope_interface_coptimizations import getObjectSpecification
+    from _zope_interface_coptimizations import ObjectSpecificationDescriptor


=== Zope3/src/zope/interface/interface.py 1.13.4.5 => 1.13.4.6 ===
--- Zope3/src/zope/interface/interface.py:1.13.4.5	Thu Oct 16 17:42:38 2003
+++ Zope3/src/zope/interface/interface.py	Thu Nov  6 07:35:10 2003
@@ -64,8 +64,83 @@
         """ Associates 'value' with 'key'. """
         self.__tagged_values[tag] = value
 
+class SpecificationBasePy(object):
 
-class Specification(object):
+    def isImplementedBy(self, ob):
+        """Is the interface implemented by an object
+
+          >>> from zope.interface import *
+          >>> class I1(Interface):
+          ...     pass
+          >>> class C:
+          ...     implements(I1)
+          >>> c = C()
+          >>> class X:
+          ...     pass
+          >>> x = X()
+          >>> I1.isImplementedBy(x)
+          False
+          >>> I1.isImplementedBy(C)
+          False
+          >>> I1.isImplementedBy(c)
+          True
+          >>> directlyProvides(x, I1)
+          >>> I1.isImplementedBy(x)
+          True
+          >>> directlyProvides(C, I1)
+          >>> I1.isImplementedBy(C)
+          True
+        
+        """
+        spec = providedBy(ob)
+        return self in spec._implied
+
+    def isImplementedByInstancesOf(self, cls):
+        """Do instances of the given class implement the interface?"""
+        spec = implementedBy(cls)
+        return self in spec._implied
+
+    def isOrExtends(self, interface):
+        """Is the interface the same as or extend the given interface
+
+        Examples::
+
+          >>> from zope.interface import Interface
+          >>> from zope.interface.declarations import Declaration
+          >>> class I1(Interface): pass
+          ...
+          >>> class I2(I1): pass
+          ...
+          >>> class I3(Interface): pass
+          ...
+          >>> class I4(I3): pass
+          ...
+          >>> spec = Declaration()
+          >>> int(spec.extends(Interface))
+          0
+          >>> spec = Declaration(I2)
+          >>> int(spec.extends(Interface))
+          1
+          >>> int(spec.extends(I1))
+          1
+          >>> int(spec.extends(I2))
+          1
+          >>> int(spec.extends(I3))
+          0
+          >>> int(spec.extends(I4))
+          0
+
+        """
+        return interface in self._implied
+
+SpecificationBase = SpecificationBasePy
+
+try:
+    from _zope_interface_coptimizations import SpecificationBase
+except ImportError:
+    pass
+
+class Specification(SpecificationBase):
     """Specifications
 
     An interface specification is used to track interface declarations
@@ -103,17 +178,15 @@
 
     >>> I3.extends(I1)
     0
-    
-    
+        
     """
 
-    def __init__(self, bases=()):
-
-        # Mapping from provided or (provided, name) or (provided,
-        # name, interfaces) -> factories This contains the transitive
-        # closure
+    # Copy some base class methods for speed
+    isOrExtends = SpecificationBase.isOrExtends
+    isImplementedBy = SpecificationBase.isImplementedBy
 
-        self._implied = {}                
+    def __init__(self, bases=()):
+        self._implied = {}
         self.dependents = weakref.WeakKeyDictionary()
         self.__bases__ = tuple(bases)
 
@@ -144,8 +217,9 @@
     def changed(self):
         """We, or something we depend on, have changed
         """
-        
-        implied = self._implied = {}
+
+        implied = self._implied
+        implied.clear()
 
         ancestors = ro(self)
         self.__iro__ = tuple([ancestor for ancestor in ancestors
@@ -161,15 +235,6 @@
             dependent.changed()
 
 
-    def isImplementedBy(self, ob):
-        spec = providedBy(ob)
-        return self in spec._implied
-
-    def isImplementedByInstancesOf(self, cls):
-        """Do instances of the given class implement the interface?"""
-        spec = implementedBy(cls)
-        return self in spec._implied
-
     def interfaces(self):
         """Return an iterator for the interfaces in the specification
 
@@ -236,6 +301,12 @@
           0
           >>> int(spec.extends(I4))
           0
+          >>> I2.extends(I2)
+          0
+          >>> I2.extends(I2, False)
+          1
+          >>> I2.extends(I2, strict=False)
+          1
 
         """
         return ((interface in self._implied)


=== Zope3/src/zope/interface/interfaces.py 1.15.8.1 => 1.15.8.2 ===
--- Zope3/src/zope/interface/interfaces.py:1.15.8.1	Sat Oct 11 10:19:03 2003
+++ Zope3/src/zope/interface/interfaces.py	Thu Nov  6 07:35:10 2003
@@ -55,7 +55,6 @@
         """Return a signature string suitable for inclusion in documentation.
         """
 
-
 class IInterface(IElement):
     """Interface objects
 
@@ -161,6 +160,13 @@
         and the other interface are the same.
         """
 
+    def isOrExtends(other):
+        """Test whether the interface is or extends another interface
+
+        A true value is returned in the interface is or extends the other
+        interface, and false otherwise.
+        """
+
     def isImplementedBy(object):
         """Test whether the interface is implemented by the object
 
@@ -468,6 +474,13 @@
         An interface specification extends an interface if it contains
         an interface that extends an interface.
         
+        """
+
+    def isOrExtends(other):
+        """Test whether the interface is or extends another interface
+
+        A true value is returned in the interface is or extends the other
+        interface, and false otherwise.
         """
 
     def __sub__(interfaces):




More information about the Zodb-checkins mailing list