summaryrefslogtreecommitdiff
path: root/src/zope/interface/declarations.py
diff options
context:
space:
mode:
authorTres Seaver <tseaver@palladion.com>2012-04-06 01:15:03 +0000
committerTres Seaver <tseaver@palladion.com>2012-04-06 01:15:03 +0000
commitf49ecd4cae67ece47e9db4faacc8460afde32812 (patch)
tree8493dcd1b6c1946f47000b9c2557dfa045c4fc50 /src/zope/interface/declarations.py
parent19fbad31cabc0a21b3fb7b0fa443d85a96edee50 (diff)
downloadzope-interface-f49ecd4cae67ece47e9db4faacc8460afde32812.tar.gz
Move commented-out doctest snippets into API docs as real snippets.
Diffstat (limited to 'src/zope/interface/declarations.py')
-rw-r--r--src/zope/interface/declarations.py601
1 files changed, 51 insertions, 550 deletions
diff --git a/src/zope/interface/declarations.py b/src/zope/interface/declarations.py
index a0f3812..f0b90f7 100644
--- a/src/zope/interface/declarations.py
+++ b/src/zope/interface/declarations.py
@@ -56,112 +56,22 @@ class Declaration(Specification):
def __contains__(self, interface):
"""Test whether an interface is in the specification
"""
- #for example:
- #
- # >>> from zope.interface import Interface
- # >>> class I1(Interface): pass
- # ...
- # >>> class I2(I1): pass
- # ...
- # >>> class I3(Interface): pass
- # ...
- # >>> class I4(I3): pass
- # ...
- # >>> spec = Declaration(I2, I3)
- # >>> spec = Declaration(I4, spec)
- # >>> int(I1 in spec)
- # 0
- # >>> int(I2 in spec)
- # 1
- # >>> int(I3 in spec)
- # 1
- # >>> int(I4 in spec)
- # 1
return self.extends(interface) and interface in self.interfaces()
def __iter__(self):
"""Return an iterator for the interfaces in the specification
"""
- # for example:
- #
- # >>> from zope.interface import Interface
- # >>> class I1(Interface): pass
- # ...
- # >>> class I2(I1): pass
- # ...
- # >>> class I3(Interface): pass
- # ...
- # >>> class I4(I3): pass
- # ...
- # >>> spec = Declaration(I2, I3)
- # >>> spec = Declaration(I4, spec)
- # >>> i = iter(spec)
- # >>> [x.getName() for x in i]
- # ['I4', 'I2', 'I3']
- # >>> list(i)
- # []
-
return self.interfaces()
def flattened(self):
"""Return an iterator of all included and extended interfaces
"""
- # for example:
- #
- # >>> from zope.interface import Interface
- # >>> class I1(Interface): pass
- # ...
- # >>> class I2(I1): pass
- # ...
- # >>> class I3(Interface): pass
- # ...
- # >>> class I4(I3): pass
- # ...
- # >>> spec = Declaration(I2, I3)
- # >>> spec = Declaration(I4, spec)
- # >>> i = spec.flattened()
- # >>> [x.getName() for x in i]
- # ['I4', 'I2', 'I1', 'I3', 'Interface']
- # >>> list(i)
- # []
-
return iter(self.__iro__)
def __sub__(self, other):
"""Remove interfaces from a specification
"""
- # Examples:
- #
- # >>> from zope.interface import Interface
- # >>> class I1(Interface): pass
- # ...
- # >>> class I2(I1): pass
- # ...
- # >>> class I3(Interface): pass
- # ...
- # >>> class I4(I3): pass
- # ...
- # >>> spec = Declaration()
- # >>> [iface.getName() for iface in spec]
- # []
- # >>> spec -= I1
- # >>> [iface.getName() for iface in spec]
- # []
- # >>> spec -= Declaration(I1, I2)
- # >>> [iface.getName() for iface in spec]
- # []
- # >>> spec = Declaration(I2, I4)
- # >>> [iface.getName() for iface in spec]
- # ['I2', 'I4']
- # >>> [iface.getName() for iface in spec - I4]
- # ['I2']
- # >>> [iface.getName() for iface in spec - I1]
- # ['I4']
- # >>> [iface.getName() for iface
- # ... in spec - Declaration(I3, I4)]
- # ['I2']
-
return Declaration(
*[i for i in self.interfaces()
if not [j for j in other.interfaces()
@@ -172,38 +82,6 @@ class Declaration(Specification):
def __add__(self, other):
"""Add two specifications or a specification and an interface
"""
- # Examples:
- #
- # >>> from zope.interface import Interface
- # >>> class I1(Interface): pass
- # ...
- # >>> class I2(I1): pass
- # ...
- # >>> class I3(Interface): pass
- # ...
- # >>> class I4(I3): pass
- # ...
- # >>> spec = Declaration()
- # >>> [iface.getName() for iface in spec]
- # []
- # >>> [iface.getName() for iface in spec+I1]
- # ['I1']
- # >>> [iface.getName() for iface in I1+spec]
- # ['I1']
- # >>> spec2 = spec
- # >>> spec += I1
- # >>> [iface.getName() for iface in spec]
- # ['I1']
- # >>> [iface.getName() for iface in spec2]
- # []
- # >>> spec2 += Declaration(I3, I4)
- # >>> [iface.getName() for iface in spec2]
- # ['I3', 'I4']
- # >>> [iface.getName() for iface in spec+spec2]
- # ['I1', 'I3', 'I4']
- # >>> [iface.getName() for iface in spec2+spec]
- # ['I3', 'I4', 'I1']
-
seen = {}
result = []
for i in self.interfaces():
@@ -247,39 +125,6 @@ def implementedByFallback(cls):
The value returned is an IDeclaration.
"""
- # For example:
- #
- # >>> from zope.interface import Interface
- # >>> class I1(Interface): pass
- # ...
- # >>> class I2(I1): pass
- # ...
- # >>> class I3(Interface): pass
- # ...
- # >>> class I4(I3): pass
- # ...
- # >>> class C1(object):
- # ... implements(I2)
- # >>> class C2(C1):
- # ... implements(I3)
- # >>> [i.getName() for i in implementedBy(C2)]
- # ['I3', 'I2']
-
- # Really, any object should be able to receive a successful answer, even
- # an instance:
- #
- # >>> class Callable(object):
- # ... def __call__(self):
- # ... return self
- #
- # >>> implementedBy(Callable())
- # <implementedBy zope.interface.declarations.?>
- #
- # Note that the name of the spec ends with a '?', because the `Callable`
- # instance does not have a `__name__` attribute.
-
- # This also manages storage of implementation specifications
-
try:
spec = cls.__dict__.get('__implemented__')
except AttributeError:
@@ -373,30 +218,6 @@ def classImplementsOnly(cls, *interfaces):
The interfaces given (including the interfaces in the specifications)
replace any previous declarations.
"""
- # Consider the following example:
- #
- # >>> from zope.interface import Interface
- # >>> class I1(Interface): pass
- # ...
- # >>> class I2(Interface): pass
- # ...
- # >>> class I3(Interface): pass
- # ...
- # >>> class I4(Interface): pass
- # ...
- # >>> class A(object):
- # ... implements(I3)
- # >>> class B(object):
- # ... implements(I4)
- # >>> class C(A, B):
- # ... pass
- # >>> classImplementsOnly(C, I1, I2)
- # >>> [i.getName() for i in implementedBy(C)]
- # ['I1', 'I2']
- #
- # Instances of ``C`` provide only ``I1``, ``I2``, and regardless of
- # whatever interfaces instances of ``A`` and ``B`` implement.
-
spec = implementedBy(cls)
spec.declared = ()
spec.inherit = None
@@ -411,35 +232,6 @@ def classImplements(cls, *interfaces):
The interfaces given (including the interfaces in the specifications)
are added to any interfaces previously declared.
"""
- # Consider the following example:
- #
- # >>> from zope.interface import Interface
- # >>> class I1(Interface): pass
- # ...
- # >>> class I2(Interface): pass
- # ...
- # >>> class I3(Interface): pass
- # ...
- # >>> class I4(Interface): pass
- # ...
- # >>> class I5(Interface): pass
- # ...
- # >>> class A(object):
- # ... implements(I3)
- # >>> class B(object):
- # ... implements(I4)
- # >>> class C(A, B):
- # ... pass
- # >>> classImplements(C, I1, I2)
- # >>> [i.getName() for i in implementedBy(C)]
- # ['I1', 'I2', 'I3', 'I4']
- # >>> classImplements(C, I5)
- # >>> [i.getName() for i in implementedBy(C)]
- # ['I1', 'I2', 'I5', 'I3', 'I4']
-
- # Instances of ``C`` provide ``I1``, ``I2``, ``I5``, and whatever
- # interfaces instances of ``A`` and ``B`` provide.
-
spec = implementedBy(cls)
spec.declared += tuple(_normalizeargs(interfaces))
@@ -469,6 +261,33 @@ def _implements_advice(cls):
class implementer:
+ """Declare the interfaces implemented by instances of a class.
+
+ This function is called as a class decorator.
+
+ The arguments are one or more interfaces or interface
+ specifications (IDeclaration objects).
+
+ The interfaces given (including the interfaces in the
+ specifications) are added to 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 classImplements. For example::
+
+ @implementer(I1)
+ class C(object):
+ pass
+
+ is equivalent to calling::
+
+ classImplements(C, I1)
+
+ after the class has been created.
+ """
def __init__(self, *interfaces):
self.interfaces = interfaces
@@ -486,6 +305,28 @@ class implementer:
return ob
class implementer_only:
+ """Declare the only interfaces implemented by instances of a class
+
+ This function is called as a class decorator.
+
+ The arguments are one or more interfaces or interface
+ specifications (IDeclaration objects).
+
+ Previous declarations including declarations for base classes
+ are overridden.
+
+ This function is provided for convenience. It provides a more
+ convenient way to call classImplementsOnly. For example::
+
+ @implementer_only(I1)
+ class C(object): pass
+
+ is equivalent to calling::
+
+ classImplementsOnly(I1)
+
+ after the class has been created.
+ """
def __init__(self, *interfaces):
self.interfaces = interfaces
@@ -595,21 +436,6 @@ class Provides(Declaration): # Really named ProvidesClass
def __get__(self, inst, cls):
"""Make sure that a class __provides__ doesn't leak to an instance
"""
- # For example:
- #
- # >>> from zope.interface import Interface
- # >>> class IFooFactory(Interface): pass
- # ...
- #
- # >>> class C(object):
- # ... pass
- #
- # >>> C.__provides__ = ProvidesClass(C, IFooFactory)
- # >>> [i.getName() for i in C.__provides__]
- # ['IFooFactory']
- # >>> getattr(C(), '__provides__', 0)
- # 0
-
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, but only if we are
@@ -630,58 +456,13 @@ def Provides(*interfaces):
Instance declarations are shared among instances that have the same
declaration. The declarations are cached in a weak value dictionary.
"""
- # (Note that, in the examples below, we are going to make assertions about
- # the size of the weakvalue dictionary. For the assertions to be
- # meaningful, we need to force garbage collection to make sure garbage
- # objects are, indeed, removed from the system. Depending on how Python
- # is run, we may need to make multiple calls to be sure. We provide a
- # collect function to help with this:
- #
- # >>> import gc
- # >>> def collect():
- # ... for i in range(4):
- # ... gc.collect()
- #
- # >>> collect()
- # >>> before = len(InstanceDeclarations)
- #
- # >>> class C(object):
- # ... pass
- #
- # >>> from zope.interface import Interface
- # >>> class I(Interface):
- # ... pass
- #
- # >>> c1 = C()
- # >>> c2 = C()
- #
- # >>> len(InstanceDeclarations) == before
- # 1
- #
- # >>> directlyProvides(c1, I)
- # >>> len(InstanceDeclarations) == before + 1
- # 1
- #
- # >>> directlyProvides(c2, I)
- # >>> len(InstanceDeclarations) == before + 1
- # 1
- #
- # >>> del c1
- # >>> collect()
- # >>> len(InstanceDeclarations) == before + 1
- # 1
- #
- # >>> del c2
- # >>> collect()
- # >>> len(InstanceDeclarations) == before
- # 1
-
spec = InstanceDeclarations.get(interfaces)
if spec is None:
spec = ProvidesClass(*interfaces)
InstanceDeclarations[interfaces] = spec
return spec
+
Provides.__safe_for_unpickling__ = True
try:
@@ -699,76 +480,6 @@ def directlyProvides(object, *interfaces):
The interfaces given (including the interfaces in the specifications)
replace interfaces previously declared for the object.
"""
- # Consider the following example:
-
- # >>> from zope.interface import Interface
- # >>> class I1(Interface): pass
- # ...
- # >>> class I2(Interface): pass
- # ...
- # >>> class IA1(Interface): pass
- # ...
- # >>> class IA2(Interface): pass
- # ...
- # >>> class IB(Interface): pass
- # ...
- # >>> class IC(Interface): pass
- # ...
- # >>> class A(object):
- # ... implements(IA1, IA2)
- # >>> class B(object):
- # ... implements(IB)
-
- # >>> class C(A, B):
- # ... implements(IC)
-
- # >>> ob = C()
- # >>> directlyProvides(ob, I1, I2)
- # >>> int(I1 in providedBy(ob))
- # 1
- # >>> int(I2 in providedBy(ob))
- # 1
- # >>> int(IA1 in providedBy(ob))
- # 1
- # >>> int(IA2 in providedBy(ob))
- # 1
- # >>> int(IB in providedBy(ob))
- # 1
- # >>> int(IC in providedBy(ob))
- # 1
- #
- # The object, ``ob`` provides ``I1``, ``I2``, and whatever interfaces
- # instances have been declared for instances of ``C``.
- #
- # To remove directly provided interfaces, use ``directlyProvidedBy`` and
- # subtract the unwanted interfaces. For example:
- #
- # >>> directlyProvides(ob, directlyProvidedBy(ob)-I2)
- # >>> int(I1 in providedBy(ob))
- # 1
- # >>> int(I2 in providedBy(ob))
- # 0
- #
- # removes I2 from the interfaces directly provided by ``ob``. The object,
- # ``ob`` no longer directly provides ``I2``, although it might still
- # provide ``I2`` if it's class implements ``I2``.
- #
- # To add directly provided interfaces, use ``directlyProvidedBy`` and
- # include additional interfaces. For example:
- #
- # >>> int(I2 in providedBy(ob))
- # 0
- # >>> directlyProvides(ob, directlyProvidedBy(ob), I2)
- #
- # adds ``I2`` to the interfaces directly provided by ob::
- #
- # >>> int(I2 in providedBy(ob))
- # 1
- #
- # We need to avoid setting this attribute on meta classes that
- # don't support descriptors.
- #
- # We can do away with this check when we get rid of the old EC
cls = getattr(object, '__class__', None)
if cls is not None and getattr(cls, '__class__', None) is cls:
# It's a meta class (well, at least it it could be an extension class)
@@ -804,99 +515,12 @@ def alsoProvides(object, *interfaces):
The interfaces given (including the interfaces in the specifications) are
added to the interfaces previously declared for the object.
"""
- # Consider the following example:
- #
- # >>> from zope.interface import Interface
- # >>> class I1(Interface): pass
- # ...
- # >>> class I2(Interface): pass
- # ...
- # >>> class IA1(Interface): pass
- # ...
- # >>> class IA2(Interface): pass
- # ...
- # >>> class IB(Interface): pass
- # ...
- # >>> class IC(Interface): pass
- # ...
- # >>> class A(object):
- # ... implements(IA1, IA2)
- # >>> class B(object):
- # ... implements(IB)
- #
- # >>> class C(A, B):
- # ... implements(IC)
- #
- # >>> ob = C()
- # >>> directlyProvides(ob, I1)
- # >>> int(I1 in providedBy(ob))
- # 1
- # >>> int(I2 in providedBy(ob))
- # 0
- # >>> int(IA1 in providedBy(ob))
- # 1
- # >>> int(IA2 in providedBy(ob))
- # 1
- # >>> int(IB in providedBy(ob))
- # 1
- # >>> int(IC in providedBy(ob))
- # 1
- #
- # >>> alsoProvides(ob, I2)
- # >>> int(I1 in providedBy(ob))
- # 1
- # >>> int(I2 in providedBy(ob))
- # 1
- # >>> int(IA1 in providedBy(ob))
- # 1
- # >>> int(IA2 in providedBy(ob))
- # 1
- # >>> int(IB in providedBy(ob))
- # 1
- # >>> int(IC in providedBy(ob))
- # 1
- #
- # The object, ``ob`` provides ``I1``, ``I2``, and whatever interfaces
- # instances have been declared for instances of ``C``. Notice that the
- # alsoProvides just extends the provided interfaces.
-
directlyProvides(object, directlyProvidedBy(object), *interfaces)
def noLongerProvides(object, interface):
""" Removes a directly provided interface from an object.
"""
- # Consider the following two interfaces:
- #
- # >>> from zope.interface import Interface
- # >>> class I1(Interface): pass
- # ...
- # >>> class I2(Interface): pass
- # ...
- #
- # ``I1`` is provided through the class, ``I2`` is directly provided
- # by the object:
- #
- # >>> class C(object):
- # ... implements(I1)
- # >>> c = C()
- # >>> alsoProvides(c, I2)
- # >>> I2.providedBy(c)
- # True
- #
- # Remove I2 from c again:
- #
- # >>> noLongerProvides(c, I2)
- # >>> I2.providedBy(c)
- # False
- #
- # Removing an interface that is provided through the class is not possible:
- #
- # >>> noLongerProvides(c, I1)
- # Traceback (most recent call last):
- # ...
- # ValueError: Can only remove directly provided interfaces.
-
- directlyProvides(object, directlyProvidedBy(object)-interface)
+ directlyProvides(object, directlyProvidedBy(object) - interface)
if interface.providedBy(object):
raise ValueError("Can only remove directly provided interfaces.")
@@ -934,22 +558,6 @@ class ClassProvides(Declaration, ClassProvidesBase):
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(object):
- # ... 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)
@@ -1008,35 +616,6 @@ def classProvides(*interfaces):
after the class has been created.
"""
- # For example:
- #
- # >>> from zope.interface import Interface
- # >>> class IFoo(Interface): pass
- # ...
- # >>> class IFooFactory(Interface): pass
- # ...
- # >>> class C(object):
- # ... implements(IFoo)
- # ... classProvides(IFooFactory)
- # >>> [i.getName() for i in C.__providedBy__]
- # ['IFooFactory']
- # >>> [i.getName() for i in C().__providedBy__]
- # ['IFoo']
- #
- # if equivalent to:
- #
- # >>> from zope.interface import Interface
- # >>> class IFoo(Interface): pass
- # ...
- # >>> class IFooFactory(Interface): pass
- # ...
- # >>> class C(object):
- # ... implements(IFoo)
- # >>> directlyProvides(C, IFooFactory)
- # >>> [i.getName() for i in C.__providedBy__]
- # ['IFooFactory']
- # >>> [i.getName() for i in C().__providedBy__]
- # ['IFoo']
if sys.version_info[0] >= 3: #pragma NO COVER
raise TypeError('Class advice impossible in Python3')
@@ -1121,66 +700,6 @@ def ObjectSpecification(direct, cls):
These combine information for the object and for it's classes.
"""
- # For example:
- #
- # >>> from zope.interface import Interface
- # >>> class I1(Interface): pass
- # ...
- # >>> class I2(Interface): pass
- # ...
- # >>> class I3(Interface): pass
- # ...
- # >>> class I31(I3): pass
- # ...
- # >>> class I4(Interface): pass
- # ...
- # >>> class I5(Interface): pass
- # ...
- # >>> class A(object):
- # ... implements(I1)
- # >>> class B(object): __implemented__ = I2
- # ...
- # >>> class C(A, B):
- # ... implements(I31)
- # >>> c = C()
- # >>> directlyProvides(c, I4)
- # >>> [i.getName() for i in providedBy(c)]
- # ['I4', 'I31', 'I1', 'I2']
- # >>> [i.getName() for i in providedBy(c).flattened()]
- # ['I4', 'I31', 'I3', 'I1', 'I2', 'Interface']
- # >>> int(I1 in providedBy(c))
- # 1
- # >>> int(I3 in providedBy(c))
- # 0
- # >>> int(providedBy(c).extends(I3))
- # 1
- # >>> int(providedBy(c).extends(I31))
- # 1
- # >>> int(providedBy(c).extends(I5))
- # 0
- # >>> class COnly(A, B):
- # ... implementsOnly(I31)
- # >>> class D(COnly):
- # ... implements(I5)
- # >>> c = D()
- # >>> directlyProvides(c, I4)
- # >>> [i.getName() for i in providedBy(c)]
- # ['I4', 'I5', 'I31']
- # >>> [i.getName() for i in providedBy(c).flattened()]
- # ['I4', 'I5', 'I31', 'I3', 'Interface']
- # >>> int(I1 in providedBy(c))
- # 0
- # >>> int(I3 in providedBy(c))
- # 0
- # >>> int(providedBy(c).extends(I3))
- # 1
- # >>> int(providedBy(c).extends(I1))
- # 0
- # >>> int(providedBy(c).extends(I31))
- # 1
- # >>> int(providedBy(c).extends(I5))
- # 1
-
return Provides(cls, direct) #pragma NO COVER fossil
def getObjectSpecificationFallback(ob):
@@ -1261,24 +780,6 @@ class ObjectSpecificationDescriptorFallback(object):
def __get__(self, inst, cls):
"""Get an object specification for an object
"""
- # For example:
- #
- # >>> from zope.interface import Interface
- # >>> class IFoo(Interface): pass
- # ...
- # >>> class IFooFactory(Interface): pass
- # ...
- # >>> class C(object):
- # ... implements(IFoo)
- # ... classProvides(IFooFactory)
- # >>> [i.getName() for i in C.__providedBy__]
- # ['IFooFactory']
- # >>> [i.getName() for i in C().__providedBy__]
- # ['IFoo']
-
- # Get an ObjectSpecification bound to either an instance or a class,
- # depending on how we were accessed.
-
if inst is None:
return getObjectSpecification(cls)