[Zodb-checkins] CVS: Zope3/src/zope/interface -
_callableimplements.py:1.1.4.1 __init__.py:1.4.6.1
_flatten.py:1.4.4.1 adapter.py:1.3.22.1
declarations.py:1.2.6.1 implementor.py:1.4.10.1
implements.py:1.4.10.1 interface.py:1.8.10.1
interfaces.py:1.12.10.1 type.py:1.7.4.1 verify.py:1.5.8.1
Jim Fulton
jim at zope.com
Fri May 2 16:43:25 EDT 2003
Update of /cvs-repository/Zope3/src/zope/interface
In directory cvs.zope.org:/tmp/cvs-serv8709/src/zope/interface
Modified Files:
Tag: interfacegeddon2-branch
__init__.py _flatten.py adapter.py declarations.py
implementor.py implements.py interface.py interfaces.py
type.py verify.py
Added Files:
Tag: interfacegeddon2-branch
_callableimplements.py
Log Message:
Merged interfacegeddon changes into second interfacegeddon branch in
preparation for the final merge.
=== Added File Zope3/src/zope/interface/_callableimplements.py ===
##############################################################################
#
# 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.
#
##############################################################################
"""Hack^H^H^Hook up zope.interface.implements as a callable module.
$Id: _callableimplements.py,v 1.1.4.1 2003/05/02 19:42:53 jim Exp $
"""
import sys
import zope.interface.implements
from zope.interface.declarations import _implements, ImplementsSpecification
Module = sys.__class__
class ImplementsModule:
def __init__(self):
self.__dict__.update(sys.modules['zope.interface.implements'].__dict__)
def __call__(self, *interfaces):
return _implements("implements", ImplementsSpecification(*interfaces))
def hookup():
global _old
_old = sys.modules['zope.interface.implements']
sys.modules['zope.interface.implements'] = ImplementsModule()
=== Zope3/src/zope/interface/__init__.py 1.4 => 1.4.6.1 ===
--- Zope3/src/zope/interface/__init__.py:1.4 Fri Apr 18 18:12:32 2003
+++ Zope3/src/zope/interface/__init__.py Fri May 2 15:42:53 2003
@@ -77,5 +77,15 @@
del _wire
from zope.interface.interface import Attribute
-from zope.interface.declarations import directlyProvides
+
+import zope.interface.implements
+from zope.interface._callableimplements import hookup
+hookup()
+del hookup
+
+from zope.interface.declarations import providedBy, implementedBy
+from zope.interface.declarations import classImplements, classImplementsOnly
+from zope.interface.declarations import directlyProvidedBy, directlyProvides
+from zope.interface.declarations import implements, implementsOnly
from zope.interface.declarations import classProvides, moduleProvides
+from zope.interface.declarations import InterfaceSpecification
=== Zope3/src/zope/interface/_flatten.py 1.4 => 1.4.4.1 ===
--- Zope3/src/zope/interface/_flatten.py:1.4 Thu May 1 15:35:44 2003
+++ Zope3/src/zope/interface/_flatten.py Fri May 2 15:42:53 2003
@@ -19,40 +19,21 @@
"""
__metaclass__ = type # All classes are new style when run with Python 2.2+
-def _flatten(implements, include_None=0):
- """Flatten an implements spec to a list of interfaces
-
- The list includes all base interfaces of the interface(s) in
- implements. Each interface is listed only once and more
- specific interfaces are listed before less specific
- interfaces. This is similar to Python 2.2's MRO.
- """
- interfaces = []
- _flatten_recurse(implements, interfaces)
- interfaces.reverse()
- seen = {}
- flattened = []
- for interface in interfaces:
- if interface not in seen:
- seen[interface] = 1
- flattened.append(interface)
- flattened.reverse()
+from zope.interface import Interface, InterfaceSpecification
- if include_None and None not in flattened:
- flattened.append(None)
+def _flatten(implements, include_None=0):
- return flattened
+ try:
+ r = implements.flattened()
+ except AttributeError:
+ if implements is None:
+ r=()
+ else:
+ r = InterfaceSpecification(implements).flattened()
-def _flatten_recurse(implements, list):
- if implements.__class__ == tuple:
- for i in implements:
- _flatten_recurse(i, list)
- else:
- _flatten_recurse_interface(implements, list)
+ if not include_None:
+ return r
-def _flatten_recurse_interface(interface, list):
- list.append(interface)
- if interface is None:
- return
- for i in interface.__bases__:
- _flatten_recurse_interface(i, list)
+ r = list(r)
+ r.append(None)
+ return r
=== Zope3/src/zope/interface/adapter.py 1.3 => 1.3.22.1 ===
--- Zope3/src/zope/interface/adapter.py:1.3 Mon Jan 20 15:02:52 2003
+++ Zope3/src/zope/interface/adapter.py Fri May 2 15:42:53 2003
@@ -19,16 +19,17 @@
"""
__metaclass__ = type # All classes are new style when run with Python 2.2+
-from zope.interface import Interface
+from zope.interface import Interface, implements, providedBy
+from zope.interface import InterfaceSpecification
from zope.interface.interfaces import IInterface
-from zope.interface._flatten import _flatten
from zope.interface.interfaces import IAdapterRegistry
+from _flatten import _flatten
class AdapterRegistry:
"""Adapter-style interface registry
"""
- __implements__ = IAdapterRegistry
+ implements(IAdapterRegistry)
# The implementation uses a mapping:
#
@@ -90,7 +91,18 @@
cache = getattr(self, '_v_cache', self)
if cache is self:
cache = self._v_cache = {}
- key = `ob_interface_provide`
+
+ # get the cache key
+ interfaces, provide = ob_interface_provide
+ try:
+ key = interfaces.__signature__
+ except AttributeError:
+ if interfaces is None:
+ key = None
+ else:
+ key = InterfaceSpecification(interfaces).__signature__
+ key = key, provide.__identifier__
+
cached = cache.get(key, self)
if cached is self:
cached = self._uncached_get(ob_interface_provide,
@@ -102,8 +114,21 @@
default, filter)
def _uncached_get(self, (ob_interface, provide), default, filter):
+
+ try:
+ flattened = ob_interface.flattened
+ except AttributeError:
+ # Somebodey (probably a test) passed us a bare interface
+ if ob_interface is not None:
+ flattened = InterfaceSpecification(ob_interface).flattened()
+ else:
+ flattened = None,
+ else:
+ flattened = flattened()
- for interface in _flatten(ob_interface, 1):
+
+ try:
+ for interface in flattened:
c = self._reg.get((interface, provide))
if c:
c = c[1]
@@ -111,12 +136,23 @@
return c
if filter(c):
return c
+ except AttributeError:
+ import pdb; pdb.set_trace()
+
+ c = self._reg.get((None, provide))
+ if c:
+ c = c[1]
+ if filter is None:
+ return c
+ if filter(c):
+ return c
+
+
return default
def getForObject(self, object, interface, filter=None):
- return self.get((getattr(object, '__implements__', None), interface),
- filter=filter)
+ return self.get((providedBy(object), interface), filter=filter)
def getRegistered(self, require, provide):
data = self._reg.get((require, provide))
=== Zope3/src/zope/interface/declarations.py 1.2 => 1.2.6.1 === (1140/1240 lines abridged)
--- Zope3/src/zope/interface/declarations.py:1.2 Wed Apr 30 16:13:23 2003
+++ Zope3/src/zope/interface/declarations.py Fri May 2 15:42:53 2003
@@ -1,87 +1,1184 @@
##############################################################################
-#
-# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# 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.
-#
##############################################################################
-"""Interfaces declarations, forward comptability versions
+"""Implementation of interface declarations
$Id$
"""
import sys
-from types import ClassType
-_ClassTypes = ClassType, type
-del ClassType
+import weakref
+from zope.interface.interface import InterfaceClass, mergeOrderings
+import exceptions
-def directlyProvides(ob, *interfaces):
-
- if isinstance(ob, _ClassTypes):
- ob.__class_implements__ = interfaces
- return
+# implementation info for immutable classes (heap flag clear)
+_implements_reg = weakref.WeakKeyDictionary()
+
+__metaclass__ = type
+
+heap = 1 << 9
+
+# Notes:
+#
+# We have 3 implementations of interface specifications:
+#
+# ImplementsSpecification
+# Holds implements specification.
[-=- -=- -=- 1140 lines omitted -=- -=- -=-]
+ raise exceptions.BadImplements(specs)
+
+ for spec in ispecs:
+ # We do this rather than isinstance because it works w proxies classes
+ if InterfaceClass in spec.__class__.__mro__:
+ if spec not in result:
+ result.append(spec)
+ elif spec is specs:
+ # Try to avoid an infinate loop by getting a string!
+ raise TypeError("Bad interface specification", spec)
+ else:
+ _flattenSpecs(spec, result)
+
+ return result
+
+def _getmro(C, r):
+ if C not in r: r.append(C)
+ for b in C.__bases__:
+ _getmro(b, r)
+ return r
+
+def _gatherSpecs(cls, result):
+ implements = _getImplements(cls)
+ if implements is not None:
+ try:
+ stop = implements.only
+ except AttributeError:
+ # Must be an old-style interface spec
+ implements = OnlyImplementsSpecification(
+ _flattenSpecs([implements], []))
+ stop = 1
+ _setImplements(cls, implements)
+
+ result.append(implements)
+ else:
+ stop = 0
+
+ if not stop:
+ for b in cls.__bases__:
+ _gatherSpecs(b, result)
+
+ return result
+
+_empty = InterfaceSpecification()
+
+
+# DocTest:
+if __name__ == "__main__":
+ import doctest, __main__
+ doctest.testmod(__main__, isprivate=lambda *a: False)
=== Zope3/src/zope/interface/implementor.py 1.4 => 1.4.10.1 ===
--- Zope3/src/zope/interface/implementor.py:1.4 Thu Apr 3 17:05:35 2003
+++ Zope3/src/zope/interface/implementor.py Fri May 2 15:42:53 2003
@@ -19,7 +19,7 @@
"""
__metaclass__ = type # All classes are new style when run with Python 2.2+
-from zope.interface import Interface
+from zope.interface import Interface, implements
from zope.interface.interfaces import IInterface
from zope.interface.interfaces import IImplementorRegistry
@@ -27,7 +27,7 @@
"""Implementor-style interface registry
"""
- __implements__ = IImplementorRegistry
+ implements(IImplementorRegistry)
# The implementation uses a mapping:
#
=== Zope3/src/zope/interface/implements.py 1.4 => 1.4.10.1 ===
--- Zope3/src/zope/interface/implements.py:1.4 Thu Apr 10 11:43:16 2003
+++ Zope3/src/zope/interface/implements.py Fri May 2 15:42:53 2003
@@ -17,42 +17,20 @@
$Id$
"""
+from zope.interface.declarations import providedBy, implementedBy
+from zope.interface.declarations import classImplements
+from zope.interface.declarations import InterfaceSpecification
+
+
from zope.interface import exceptions
from zope.interface.verify import verifyClass
from zope.interface.interface import InterfaceClass
from types import TupleType, ClassType, StringType
-# Special value indicating the object supports
-# what its class supports.
-CLASS_INTERFACES = 1
-
-ClassTypes = ClassType, type
-
-_typeImplements = {}
-
-def getImplements(object):
- # Decide whether or not the object is a class. If it is a class,
- # return it's __class_implements__ rather than its __implements__.
- if isinstance(object, ClassTypes):
- ci = getattr(object, '__class_implements__', None)
- if ci is not None:
- return ci
- else:
- impl = getattr(object, '__implements__', None)
- if impl is not None:
- return impl
-
- return _typeImplements.get(type(object))
-
+getImplements = providedBy
+getImplementsOfInstances = implementedBy
-def getImplementsOfInstances(klass):
- if isinstance(klass, ClassTypes):
- return getattr(klass, '__implements__', None)
- else:
- return _typeImplements.get(klass)
-
-
-def visitImplements(implements, object, visitor, getInterface=None):
+def visitImplements(implements, object, visitor):
"""Call visitor for each interace.
Visits the interfaces described by an __implements__ attribute,
@@ -60,76 +38,27 @@
If the visitor returns anything true, the loop stops.
This does not, and should not, visit superinterfaces.
"""
- # this allows us to work with proxy wrappers in Python 2.2,
- # yet remain compatible with earlier versions of python.
- implements_class = getattr(implements, '__class__', None)
-
- if InterfaceClass in implements_class.__mro__:
- return visitor(implements)
- elif implements == CLASS_INTERFACES:
- klass = getattr(object, '__class__', None)
- if klass is not None:
- i = getImplementsOfInstances(klass)
- if i:
- return visitImplements(i, object, visitor, getInterface)
- elif implements_class == StringType or type(implements) is StringType:
- if getInterface is not None:
- # Look up a named interface.
- i = getInterface(object, implements)
- if i is not None:
- return visitImplements(i, object, visitor, getInterface)
- elif implements_class == TupleType or type(implements) is TupleType:
- for i in implements:
- r = visitImplements(i, object, visitor, getInterface)
- if r:
- # If the visitor returns anything true, stop.
- return r
- else:
- if implements_class is not None and \
- type(implements) != implements_class:
- raise exceptions.BadImplements(
- """__implements__ should be an interface or tuple,
- not a %s pretending to be a %s"""
- % (type(implements).__name__, implements_class.__name__)
- )
- raise exceptions.BadImplements(
- """__implements__ should be an interface or tuple,
- not a %s""" % type(implements).__name__)
- return None
-
-
-def assertTypeImplements(type, interfaces):
- """Assign a set of interfaces to a Python type such as int, str, tuple,
- list and dict.
- """
- _typeImplements[type] = interfaces
-def objectImplements(object, getInterface=None):
- r = []
- implements = getImplements(object)
- if not implements:
- return r
- visitImplements(implements, object, r.append, getInterface)
- return r
-
-def instancesOfObjectImplements(klass, getInterface=None):
- r = []
- implements = getImplementsOfInstances(klass)
- if not implements:
- return r
- visitImplements(implements, klass, r.append, getInterface)
- return r
+ for interface in InterfaceSpecification(implements):
+ if visitor(interface):
+ break
+
+
+assertTypeImplements = classImplements
+
+objectImplements = providedBy
+instancesOfObjectImplements = implementedBy
def _flatten(i, append):
- if isinstance(i, (list, tuple)):
- for iface in i:
- _flatten(iface, append)
- else:
+ if InterfaceClass in i.__class__.__mro__:
append(i)
bases = i.getBases()
if bases:
for b in bases:
_flatten(b, append)
+ else:
+ for iface in i:
+ _flatten(iface, append)
def flattenInterfaces(interfaces, remove_duplicates=1):
res = []
=== Zope3/src/zope/interface/interface.py 1.8 => 1.8.10.1 ===
--- Zope3/src/zope/interface/interface.py:1.8 Mon Apr 14 04:29:09 2003
+++ Zope3/src/zope/interface/interface.py Fri May 2 15:42:53 2003
@@ -17,6 +17,7 @@
$Id$
"""
+import sys
from inspect import currentframe
from types import FunctionType
@@ -75,17 +76,22 @@
__module__=None):
if __module__ is None:
- if attrs is not None and ('__module__' in attrs):
+ if (attrs is not None and
+ ('__module__' in attrs) and
+ isinstance(attrs['__module__'], str)
+ ):
__module__ = attrs['__module__']
del attrs['__module__']
else:
+
try:
# Figure out what module defined the interface.
# This is how cPython figures out the module of
# a class, but of course it does it in C. :-/
- __module__ = currentframe().f_back.f_globals['__name__']
+ __module__ = sys._getframe(1).f_globals['__name__']
except (AttributeError, KeyError):
pass
+
self.__module__ = __module__
for b in bases:
@@ -108,6 +114,8 @@
Element.__init__(self, name, __doc__)
+ self.__iro__ = mergeOrderings([_flattenInterface(self, [])])
+
for k, v in attrs.items():
if isinstance(v, Attribute):
v.interface = name
@@ -120,6 +128,9 @@
self.__attrs = attrs
+ self.__identifier__ = "%s.%s" % (self.__module__, self.__name__)
+
+
def getBases(self):
return self.__bases__
@@ -143,34 +154,25 @@
"""Does the given object implement the interface?"""
# OPT Cache implements lookups
- implements = getImplements(object)
- if implements is None:
- return False
-
+ implements = providedBy(object)
cache = getattr(self, '_v_cache', self)
if cache is self:
cache = self._v_cache = {}
- key = `implements`
+
+ key = implements.__signature__
r = cache.get(key)
if r is None:
- r = bool(
- visitImplements(
- implements, object, self.isEqualOrExtendedBy,
- self._getInterface)
- )
+ r = bool(implements.extends(self))
cache[key] = r
return r
def isImplementedByInstancesOf(self, klass):
"""Do instances of the given class implement the interface?"""
- i = getImplementsOfInstances(klass)
- if i is not None:
- return visitImplements(
- i, klass, self.isEqualOrExtendedBy, self._getInterface)
- return False
+ i = implementedBy(klass)
+ return bool(i.extends(self))
def names(self, all=False):
"""Return the attribute names defined by the interface."""
@@ -329,7 +331,48 @@
return c > 0
-Interface = InterfaceClass("Interface")
+def mergeOrderings(orderings, seen=None):
+ """Merge multiple orderings so that within-ordering order is preserved
+
+ Orderings are constrained in such a way that if an object appears
+ in two or more orderings, then the suffix that begins with the
+ object must be in both orderings.
+
+ For example:
+
+ >>> _mergeOrderings([
+ ... ['x', 'y', 'z'],
+ ... ['q', 'z'],
+ ... [1, 3, 5],
+ ... ['z']
+ ... ])
+ ['x', 'y', 'q', 1, 3, 5, 'z']
+
+ """
+
+ if seen is None:
+ seen = {}
+ result = []
+ orderings.reverse()
+ for ordering in orderings:
+ ordering = list(ordering)
+ ordering.reverse()
+ for o in ordering:
+ if o not in seen:
+ seen[o] = 1
+ result.append(o)
+
+ result.reverse()
+ return result
+
+def _flattenInterface(iface, result):
+ result.append(iface)
+ for base in iface.__bases__:
+ _flattenInterface(base, result)
+
+ return result
+
+Interface = InterfaceClass("Interface", __module__ = 'zope.interface')
class Attribute(Element):
"""Attribute descriptions
@@ -427,23 +470,21 @@
func = meth.im_func
return fromFunction(func, interface, imlevel=1)
+
# Now we can create the interesting interfaces and wire them up:
def _wire():
-
- from zope.interface.implements import implements
+ from zope.interface.declarations import classImplements
from zope.interface.interfaces import IAttribute
- implements(Attribute, IAttribute)
+ classImplements(Attribute, IAttribute)
from zope.interface.interfaces import IMethod
- implements(Method, IMethod)
+ classImplements(Method, IMethod)
from zope.interface.interfaces import IInterface
- implements(InterfaceClass, IInterface)
+ classImplements(InterfaceClass, IInterface)
# We import this here to deal with module dependencies.
-from zope.interface.implements import getImplementsOfInstances
-from zope.interface.implements import visitImplements, getImplements
-from zope.interface.implements import instancesOfObjectImplements
+from zope.interface.declarations import providedBy, implementedBy
from zope.interface.exceptions import InvalidInterface
from zope.interface.exceptions import BrokenImplementation
=== Zope3/src/zope/interface/interfaces.py 1.12 => 1.12.10.1 ===
--- Zope3/src/zope/interface/interfaces.py:1.12 Thu Apr 3 17:05:35 2003
+++ Zope3/src/zope/interface/interfaces.py Fri May 2 15:42:53 2003
@@ -125,51 +125,30 @@
There are several ways that you can assert that an object
implements an interface::
- 1. Include an '__implements__' attribute in the object's class
- definition. The value of the '__implements__' attribute must
- be an implementation specification. An implementation
- specification is either an interface or a tuple of
- implementation specifications.
-
- 2. Incluse an '__implements__' attribute in the object.
- Because Python classes don't have their own attributes, to
- assert that a class implements interfaces, you must provide a
- '__class_implements__' attribute in the class definition.
-
- **Important**: A class usually doesn't implement the
- interfaces that its instances implement. The class and
- its instances are separate objects with their own
- interfaces.
+ 1. Call zope.interface.implements in your class definition.
- 3. Call 'Interface.Implements.implements' to assert that instances
+ 2. Call zope.interfaces.directlyProvides on your object.
+
+ 3. Call 'zope.interface.classImplements' to assert that instances
of a class implement an interface.
For example::
- from zope.interface.implements import implements
+ from zope.interface import classImplements
- implements(some_class, some_interface)
+ classImplements(some_class, some_interface)
This is approach is useful when it is not an option to modify
the class source. Note that this doesn't affect what the
class itself implements, but only what its instances
implement.
- 4. For types that can't be modified, you can assert that
- instances of the type implement an interface using
- 'Interface.Implements.assertTypeImplements'.
-
- For example::
-
- from zope.interface.implements import assertTypeImplements
-
- assertTypeImplements(some_type, some_interface)
-
o You query interface meta-data. See the IInterface methods and
attributes for details.
"""
+
def getBases():
"""Return a sequence of the base interfaces."""
@@ -239,7 +218,12 @@
returned.
"""
- get = queryDescriptionFor
+ def get(name, default=None):
+ """Look up the description for a name
+
+ If the named attribute is not defined, the default is
+ returned.
+ """
def __contains__(name):
"""Test whether the name is defined by the interface"""
@@ -251,6 +235,28 @@
interface directly and indirectly by base interfaces.
"""
+ __module__ = Attribute("""The name of the module defining the interface""")
+
+ __bases__ = Attribute("""A tuple of base interfaces""")
+ __iro__ = Attribute(
+ """A tuple of all interfaces extended by the interface
+
+ The first item in the tuple is the interface itself. The
+ interfaces are listed in order from most specific to most
+ general, preserving the original order of base interfaces
+ where possible.
+
+ """)
+
+ __identifier__ = Attribute("""A unique identifier for the interface
+
+ This identifier should be different for different interfaces.
+
+ The identifier is not allowed to contain tab characters.
+ """)
+
+
+
class ITypeRegistry(Interface):
"""Type-specific registry
@@ -444,88 +450,6 @@
"""
-
-class IImplements(Interface):
- """Functions for reasoning about implementation assertions
- """
-
- def getImplements(object):
- """Return an interface specification for an object
-
- Returns the interfaces that an object asserts that it implements.
- """
-
- def getImplementsOfInstances(class_):
- """Return the interface specification ofr instances of a class
-
- Returns the interfaces that a class asserts that it's
- instances implement.
-
- """
-
- def visitImplements(implements, object, visitor, getInterface=None):
- """Call visitor for each interace in an interface specification
-
- The interface specification is given as the first argument. It
- should be gotten by calling getImplements on an object, but
- often object.__implements__ is passed.
-
- The second argument is the object that implements the
- interface. It is used for special experimental interface
- features. (IOW, it is a burnt offering).
-
- The third argument is a callable that will be called for each
- interface in the specification.
-
- The getImplements argument is a hook that will be called if a
- certian experimental (and soon to be removed) feature is used
- in the interface specification.
-
- This method will soon be depricated.
-
- """
-
- def assertTypeImplements(type, interface):
- """Assert that instances of a type implement an interface.
- """
-
- def objectImplements(object, getInterface=None):
- """Get a sequence of the interfaces the object implements
-
- The getImplements argument is a hook that will be called if a
- certian experimental (and soon to be removed) feature is used
- in the interface specification.
-
- """
-
- def instancesOfObjectImplements(class_, getInterface=None):
- """Get a sequence of the interfaces instances of the class implements
-
- The getImplements argument is a hook that will be called if a
- certian experimental (and soon to be removed) feature is used
- in the interface specification.
-
- """
-
- def flattenInterfaces(interfaces, remove_duplicates=True):
- """Get a sequence of the interfaces in an interface specification
-
- The result includes all base interfaces of the interfaces in
- the specification.
-
- If remove_duplicates is true, then duplicate interfaces are
- removed. The interfaces are included in order from most
- specifgic to most general.
- """
-
- def implements(class_, interface, check=True):
- """Assert that instanced of a class implement the given interface
-
- If the check argument is true, the class will be checked to
- see if it obviously fails the assertion.
- """
-
-
class IInterfaceSpecification(Interface):
def __contains__(interface):
@@ -551,6 +475,14 @@
were defined in the specification.
"""
+ def extends(interface):
+ """Test whether an interface specification extends an interface
+
+ An interface specification extends an interface if it contains
+ an interface that extends an interface.
+
+ """
+
def __sub__(interfaces):
"""Create an interface specification with some interfaces excluded
@@ -560,6 +492,9 @@
Removing an interface that is not in the specification does
not raise an error. Doing so has no effect.
+
+ Removing an interface also removes subinterfaces of the interface.
+
"""
def __add__(interfaces):
@@ -573,8 +508,22 @@
not raise an error. Doing so has no effect.
"""
+ __signature__ = Attribute("""A specification signature
+
+ The signature should change if any of the interfaces in the
+ specification change.
+
+ """)
-class IImplements(Interface):
+ only = Attribute("""\
+ A flag (boolean) indicating whether a specification extends others
+
+ If only is true, then a class implementing the specification
+ doesn't implement base-class specifications.
+
+ """)
+
+class IInterfaceDeclaration(Interface):
"""Declare and check the interfaces of objects
The functions defined in this interface are used to declare the
@@ -656,29 +605,6 @@
whatever interfaces instances of ``A`` and ``B`` implement.
"""
- def classUnimplements(class_, *interfaces):
- """Declare the interfaces not implemented for instances of a class
-
- The arguments after the class are one or more interfaces or
- interface specifications (IInterfaceSpecification objects).
-
- The interfaces given (including the interfaces in the
- specifications) cancel previous declarations for the same
- interfaces, including declarations made in base classes.
-
- Consider the following example::
-
- class C(A, B):
- ...
-
- classImplements(C, I1)
- classUnimplements(C, I1, I2)
-
-
- Instances of ``C`` don't provide ``I1`` and ``I2`` even if
- instances of ``A`` or ``B`` do.
- """
-
def directlyProvidedBy(object):
"""Return the interfaces directly provided by the given object
@@ -792,42 +718,6 @@
instances of ``A`` and ``B`` implement.
"""
- def unimplements(*interfaces):
- """Declare interfaces not implemented by instances of a class
-
- This function is called in a class definition.
-
- The arguments are one or more interfaces or interface
- specifications (IInterfaceSpecification objects).
-
- The interfaces given (including the interfaces in the
- specifications) are removed from any interfaces previously
- declared.
-
- Previous declarations include declarations for base classes
- unless implementsOnly was used.
-
- This function is provided for convenience. It provides a more
- convenient way to call classUnimplements. For example::
-
- unimplements(I1)
-
- is equivalent to calling::
-
- classUnimplements(I1)
-
- after the class has been created.
-
- Consider the following example::
-
- class C(A, B):
- unimplements(I1, I2)
-
-
- Instances of ``C`` don't implement ``I1``, ``I2``, even if
- instances of ``A`` and ``B`` do.
- """
-
def classProvides(*interfaces):
"""Declare interfaces provided directly by a class
@@ -891,4 +781,71 @@
A new interface specification (IInterfaceSpecification) with
the given interfaces is returned.
+ """
+
+class IInterfaceDeclarationYAGNI(Interface):
+ """YAGNI interface declaration API
+
+ The functions in this interface are functions that might be
+ provided later, but that introduce difficulties that we choose to
+ avoid now.
+ """
+
+ def unimplements(*interfaces):
+ """Declare interfaces not implemented by instances of a class
+
+ This function is called in a class definition.
+
+ The arguments are one or more interfaces or interface
+ specifications (IInterfaceSpecification objects).
+
+ The interfaces given (including the interfaces in the
+ specifications) are removed from any interfaces previously
+ declared.
+
+ Previous declarations include declarations for base classes
+ unless implementsOnly was used.
+
+ This function is provided for convenience. It provides a more
+ convenient way to call classUnimplements. For example::
+
+ unimplements(I1)
+
+ is equivalent to calling::
+
+ classUnimplements(I1)
+
+ after the class has been created.
+
+ Consider the following example::
+
+ class C(A, B):
+ unimplements(I1, I2)
+
+
+ Instances of ``C`` don't implement ``I1``, ``I2``, even if
+ instances of ``A`` and ``B`` do.
+ """
+
+ def classUnimplements(class_, *interfaces):
+ """Declare the interfaces not implemented for instances of a class
+
+ The arguments after the class are one or more interfaces or
+ interface specifications (IInterfaceSpecification objects).
+
+ The interfaces given (including the interfaces in the
+ specifications) cancel previous declarations for the same
+ interfaces, including declarations made in base classes.
+
+ Consider the following example::
+
+ class C(A, B):
+ ...
+
+ classImplements(C, I1)
+ classUnimplements(C, I1, I2)
+
+
+ Instances of ``C`` don't provide ``I1`` and ``I2`` even if
+ instances of ``A`` or ``B`` do.
"""
=== Zope3/src/zope/interface/type.py 1.7 => 1.7.4.1 ===
--- Zope3/src/zope/interface/type.py:1.7 Thu May 1 15:35:44 2003
+++ Zope3/src/zope/interface/type.py Fri May 2 15:42:53 2003
@@ -19,8 +19,8 @@
"""
__metaclass__ = type # All classes are new style when run with Python 2.2+
+from zope.interface import Interface, providedBy
from zope.interface.interfaces import IInterface
-from zope.interface._flatten import _flatten
from zope.interface.interfaces import ITypeRegistry
class TypeRegistry:
@@ -72,7 +72,7 @@
def getAll(self, interface_spec):
result = []
- for interface in _flatten(interface_spec):
+ for interface in interface_spec.flattened():
object = self._reg.get(interface)
if object is not None:
result.append(object)
@@ -88,7 +88,7 @@
# XXX This isn't quite right, since it doesn't take into
# account implementation registries for objects that can't
# have '__implements__' attributes.
- return self.getAll(getattr(object, '__implements__', None))
+ return self.getAll(providedBy(object))
def getTypesMatching(self, interface):
if interface is None:
=== Zope3/src/zope/interface/verify.py 1.5 => 1.5.8.1 ===
--- Zope3/src/zope/interface/verify.py:1.5 Fri Apr 18 09:59:54 2003
+++ Zope3/src/zope/interface/verify.py Fri May 2 15:42:53 2003
@@ -15,7 +15,7 @@
from zope.interface.exceptions import BrokenImplementation, DoesNotImplement
from zope.interface.exceptions import BrokenMethodImplementation
from types import FunctionType, MethodType
-from zope.interface.interface import fromMethod, fromFunction
+from zope.interface.interface import fromMethod, fromFunction, Method
# This will be monkey-patched when running under Zope 2, so leave this
# here:
@@ -49,6 +49,11 @@
for n, d in iface.namesAndDescriptions(1):
if not hasattr(candidate, n):
+ if (not isinstance(d, Method)) and vtype == 'c':
+ # We can't verify non-methods on classes, since the
+ # class may provide attrs in it's __init__.
+ continue
+
raise BrokenImplementation(iface, n)
attr = getattr(candidate, n)
More information about the Zodb-checkins
mailing list