diff options
| author | Jason Madden <jamadden@gmail.com> | 2018-07-19 12:09:08 -0500 |
|---|---|---|
| committer | Jason Madden <jamadden@gmail.com> | 2018-07-19 12:09:08 -0500 |
| commit | bf6228076dd86bc51acf325025d544394cd07773 (patch) | |
| tree | e08bc3921843a3fa3d137281becee596d03c7067 /docs | |
| parent | 0416521d87e35a3af3755cfd5e0234e92c067811 (diff) | |
| download | zope-interface-bf6228076dd86bc51acf325025d544394cd07773.tar.gz | |
Reorganize the 'declarations' document by functional group.
Add cross references and some formatting fixes.
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/api/declarations.rst | 890 |
1 files changed, 401 insertions, 489 deletions
diff --git a/docs/api/declarations.rst b/docs/api/declarations.rst index 25bc9a2..98bc226 100644 --- a/docs/api/declarations.rst +++ b/docs/api/declarations.rst @@ -1,258 +1,68 @@ -========================================= - API for ``zope.interface.declarations`` -========================================= +================================================== + Declaring and Checking The Interfaces of Objects +================================================== +Declaring what interfaces an object implements or provides, and later +being able to check those, is an important part of this package. +Declaring interfaces, in particular, can be done both statically at +object definition time and dynamically later on. -``Declaration`` -=============== +The functionality that allows declaring and checking interfaces is +provided directly in the ``zope.interface`` module. It is described by +the interface ``zope.interface.interfaces.IInterfaceDeclaration``. We +will first look at that interface, and then we will look more +carefully at each object it documents, including providing examples. +.. autointerface:: zope.interface.interfaces.IInterfaceDeclaration -API ---- -Declaration objects implement the API defined by -:class:`zope.interface.interfaces.IDeclaration`: +.. currentmodule:: zope.interface.declarations -.. autointerface:: zope.interface.interfaces.IDeclaration - :members: - :member-order: bysource +Declaring The Interfaces of Objects +=================================== -.. autoclass:: zope.interface.declarations.Declaration -Usage ------ +implementer +----------- -Exmples for :meth:`Declaration.__contains__`: +.. autoclass:: implementer -.. doctest:: - >>> from zope.interface.declarations import Declaration - >>> 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 +implementer_only +---------------- -Exmples for :meth:`Declaration.__iter__`: +.. autoclass:: implementer_only -.. doctest:: - >>> 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) - [] - -Exmples for :meth:`Declaration.flattened`: - -.. doctest:: - - >>> 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) - [] - -Exmples for :meth:`Declaration.__sub__`: - -.. doctest:: - - >>> 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'] +implements +---------- -Exmples for :meth:`Declaration.__add__`: +(The `implementer` decorator is preferred to this.) -.. doctest:: +.. autofunction:: implements - >>> 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'] +implementsOnly +-------------- +(The `implementer_only` decorator is preferred to this.) -``implementedBy`` -================= +.. autofunction:: implementsOnly -API ---- -.. autofunction:: zope.interface.declarations.implementedByFallback +classImplementsOnly +------------------- +.. autofunction:: classImplementsOnly -Usage ------ Consider the following example: .. doctest:: - >>> from zope.interface import Interface + >>> from zope.interface import implementedBy >>> from zope.interface import implements >>> from zope.interface import classImplementsOnly - >>> from zope.interface import implementedBy - >>> 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. - -Another example: - -.. doctest:: - - >>> 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: - -.. doctest:: - - >>> class Callable(object): - ... def __call__(self): - ... return self - >>> implementedBy(Callable()) - <implementedBy __builtin__.?> - -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. - - - -``classImplementsOnly`` -======================= - -API ---- - -.. autofunction:: zope.interface.declarations.classImplementsOnly - - -Usage ------ - -Consider the following example: - -.. doctest:: - >>> from zope.interface import Interface >>> class I1(Interface): pass ... @@ -276,18 +86,10 @@ Instances of ``C`` provide only ``I1``, ``I2``, and regardless of whatever interfaces instances of ``A`` and ``B`` implement. +classImplements +--------------- -``classImplements`` -=================== - -API ---- - -.. autofunction:: zope.interface.declarations.classImplements - - -Usage ------ +.. autofunction:: classImplements Consider the following example: @@ -322,157 +124,19 @@ Instances of ``C`` provide ``I1``, ``I2``, ``I5``, and whatever interfaces instances of ``A`` and ``B`` provide. +directlyProvides +---------------- -``implementer`` -=============== - -API ---- - -.. autoclass:: zope.interface.declarations.implementer - :members: - :member-order: bysource - - - -``implementer_only`` -==================== - -API ---- - -.. autoclass:: zope.interface.declarations.implementer_only - :members: - :member-order: bysource - - - -``implements`` -============== - -API ---- - -.. autofunction:: zope.interface.declarations.implements - - -``implementsOnly`` -================== - -API ---- - -.. autofunction:: zope.interface.declarations.implementsOnly - - - - -``ProvidesClass`` -================= - -API ---- - -.. autoclass:: zope.interface.declarations.ProvidesClass - :members: - :member-order: bysource - - -Usage ------ - -Descriptor semantics (via ``Provides.__get__``): - -.. doctest:: - - >>> from zope.interface import Interface - >>> class IFooFactory(Interface): pass - ... - >>> class C(object): - ... pass - >>> from zope.interface.declarations import ProvidesClass - >>> C.__provides__ = ProvidesClass(C, IFooFactory) - >>> [i.getName() for i in C.__provides__] - ['IFooFactory'] - >>> getattr(C(), '__provides__', 0) - 0 +.. autofunction:: directlyProvides - - -``Provides`` -============ - -API ---- - -.. autofunction:: zope.interface.declarations.Provides - - -Usage ------ - -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: - -.. doctest:: - - >>> import gc - >>> def collect(): - ... for i in range(4): - ... gc.collect() - >>> collect() - >>> from zope.interface import directlyProvides - >>> from zope.interface.declarations import InstanceDeclarations - >>> before = len(InstanceDeclarations) - >>> class C(object): - ... pass - >>> from zope.interface import Interface - >>> class I(Interface): - ... pass - >>> c1 = C() - >>> c2 = C() - >>> len(InstanceDeclarations) == before - True - >>> directlyProvides(c1, I) - >>> len(InstanceDeclarations) == before + 1 - True - >>> directlyProvides(c2, I) - >>> len(InstanceDeclarations) == before + 1 - True - >>> del c1 - >>> collect() - >>> len(InstanceDeclarations) == before + 1 - True - >>> del c2 - >>> collect() - >>> len(InstanceDeclarations) == before - True - - - -``directlyProvides`` -==================== - -API ---- - -.. autofunction:: zope.interface.declarations.directlyProvides - - -Usage ------ - Consider the following example: .. doctest:: >>> from zope.interface import Interface >>> from zope.interface import providedBy + >>> from zope.interface import directlyProvides >>> class I1(Interface): pass ... >>> class I2(Interface): pass @@ -548,18 +212,11 @@ don't support descriptors. We can do away with this check when we get rid of the old EC +alsoProvides +------------ -``alsoProvides`` -================ +.. autofunction:: alsoProvides -API ---- - -.. autofunction:: zope.interface.declarations.alsoProvides - - -Usage ------ Consider the following example: @@ -618,18 +275,10 @@ instances have been declared for instances of ``C``. Notice that the ``alsoProvides`` just extends the provided interfaces. +noLongerProvides +---------------- -``noLongerProvides`` -==================== - -API ---- - -.. autofunction:: zope.interface.declarations.noLongerProvides - - -Usage ------ +.. autofunction:: noLongerProvides Consider the following two interfaces: @@ -672,28 +321,11 @@ Removing an interface that is provided through the class is not possible: ValueError: Can only remove directly provided interfaces. +classProvides +------------- -``directlyProvidedBy`` -====================== - -API ---- - -.. autofunction:: zope.interface.declarations.directlyProvidedBy - - - -``classProvides`` -================= - -API ---- +.. autofunction:: classProvides -.. autofunction:: zope.interface.declarations.classProvides - - -Usage ------ For example: @@ -733,40 +365,371 @@ Which is equivalent to: ['IFoo'] +provider +-------- + +.. autoclass:: provider + -``provider`` -============ +moduleProvides +-------------- -API ---- +.. autofunction:: moduleProvides + + +named +----- + +.. autoclass:: zope.interface.declarations.named -.. autoclass:: zope.interface.declarations.provider +For example: + +.. doctest:: + + >>> from zope.interface.declarations import named + + >>> @named('foo') + ... class Foo(object): + ... pass + + >>> Foo.__component_name__ + 'foo' + +When registering an adapter or utility component, the registry looks for the +``__component_name__`` attribute and uses it, if no name was explicitly +provided. + + +Querying The Interfaces Of Objects +================================== + +All of these functions return an +`~zope.interface.interfaces.IDeclaration`. +You'll notice that an ``IDeclaration`` is a type of +`~zope.interface.interfaces.ISpecification`, as is +``zope.interface.Interface``, so they share some common behaviour. + +.. autointerface:: zope.interface.interfaces.IDeclaration :members: :member-order: bysource -``moduleProvides`` -================== +implementedBy +------------- -API ---- +.. autofunction:: implementedByFallback -.. autofunction:: zope.interface.declarations.moduleProvides +Consider the following example: +.. doctest:: + >>> from zope.interface import Interface + >>> from zope.interface import implements + >>> from zope.interface import classImplementsOnly + >>> from zope.interface import implementedBy + >>> 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'] -``ObjectSpecification`` -======================= +Instances of ``C`` provide only ``I1``, ``I2``, and regardless of +whatever interfaces instances of ``A`` and ``B`` implement. -API ---- +Another example: -.. autofunction:: zope.interface.declarations.ObjectSpecification +.. doctest:: + >>> 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: + +.. doctest:: + + >>> class Callable(object): + ... def __call__(self): + ... return self + >>> implementedBy(Callable()) + <implementedBy __builtin__.?> + +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. + + +providedBy +---------- + +.. autofunction:: providedBy + + +directlyProvidedBy +------------------ + +.. autofunction:: directlyProvidedBy + + +Classes +======= + + +Declarations +------------ + +Declaration objects implement the API defined by +:class:`~zope.interface.interfaces.IDeclaration`. + + +.. autoclass:: Declaration + + +Exmples for :meth:`Declaration.__contains__`: + +.. doctest:: + + >>> from zope.interface.declarations import Declaration + >>> 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 + +Exmples for :meth:`Declaration.__iter__`: + +.. doctest:: + + >>> 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) + [] + +Exmples for :meth:`Declaration.flattened`: + +.. doctest:: + + >>> 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) + [] + +Exmples for :meth:`Declaration.__sub__`: + +.. doctest:: + + >>> 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'] + +Exmples for :meth:`Declaration.__add__`: + +.. doctest:: + + >>> 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'] + + + +ProvidesClass +------------- + +.. autoclass:: ProvidesClass + + +Descriptor semantics (via ``Provides.__get__``): + +.. doctest:: + + >>> from zope.interface import Interface + >>> class IFooFactory(Interface): pass + ... + >>> class C(object): + ... pass + >>> from zope.interface.declarations import ProvidesClass + >>> C.__provides__ = ProvidesClass(C, IFooFactory) + >>> [i.getName() for i in C.__provides__] + ['IFooFactory'] + >>> getattr(C(), '__provides__', 0) + 0 + + +Implementation Details +====================== + +The following section discusses some implementation details and +demonstrates their use. You'll notice that they are all demonstrated +using the previously-defined functions. + +Provides +-------- + +.. autofunction:: Provides + +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: + +.. doctest:: + + >>> import gc + >>> def collect(): + ... for i in range(4): + ... gc.collect() + >>> collect() + >>> from zope.interface import directlyProvides + >>> from zope.interface.declarations import InstanceDeclarations + >>> before = len(InstanceDeclarations) + >>> class C(object): + ... pass + >>> from zope.interface import Interface + >>> class I(Interface): + ... pass + >>> c1 = C() + >>> c2 = C() + >>> len(InstanceDeclarations) == before + True + >>> directlyProvides(c1, I) + >>> len(InstanceDeclarations) == before + 1 + True + >>> directlyProvides(c2, I) + >>> len(InstanceDeclarations) == before + 1 + True + >>> del c1 + >>> collect() + >>> len(InstanceDeclarations) == before + 1 + True + >>> del c2 + >>> collect() + >>> len(InstanceDeclarations) == before + True + + +ObjectSpecification +------------------- + +.. autofunction:: ObjectSpecification -Usage ------ For example: @@ -831,30 +794,10 @@ For example: >>> int(providedBy(c).extends(I5)) 1 +ObjectSpecificationDescriptor +----------------------------- - -``providedBy`` -============== - -API ---- - -.. autofunction:: zope.interface.declarations.providedBy - - - -``ObjectSpecificationDescriptor`` -================================= - -API ---- - -.. autoclass:: zope.interface.declarations.ObjectSpecificationDescriptor - :members: - :member-order: bysource - -Usage ------ +.. autoclass:: ObjectSpecificationDescriptor For example: @@ -875,34 +818,3 @@ For example: Get an ObjectSpecification bound to either an instance or a class, depending on how we were accessed. - - -``named`` -========= - -API ---- - -.. autoclass:: zope.interface.declarations.named - :members: - :member-order: bysource - -Usage ------ - -For example: - -.. doctest:: - - >>> from zope.interface.declarations import named - - >>> @named('foo') - ... class Foo(object): - ... pass - - >>> Foo.__component_name__ - 'foo' - -When registering an adapter or utility component, the registry looks for the -``__component_name__`` attribute and uses it, if no name was explicitly -provided. |
