[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