summaryrefslogtreecommitdiff
path: root/docs/socketexample.rst
diff options
context:
space:
mode:
authorJason Madden <jamadden@gmail.com>2017-06-29 10:28:28 -0500
committerJason Madden <jamadden@gmail.com>2017-06-29 11:44:12 -0500
commit891ada316770d5c60a7124beb1a1e589483c8ccf (patch)
treebadc71ee3ad8de2edbb0845bc10db5509fd37ee7 /docs/socketexample.rst
parent45b227fb64ea8dd5ceb1aa5e2ede4649e0c55ae4 (diff)
downloadzope-component-891ada316770d5c60a7124beb1a1e589483c8ccf.tar.gz
Enable doctests on Python 3 and PyPy
Drop pypy3.3-5.5-alpha Sphinx needs Python 2.7 or 3.4+ to run, and this is a (really old) version of Python 3.3. (Unfortunately the beta of PyPy3.5 does not appear to be available.)
Diffstat (limited to 'docs/socketexample.rst')
-rw-r--r--docs/socketexample.rst111
1 files changed, 63 insertions, 48 deletions
diff --git a/docs/socketexample.rst b/docs/socketexample.rst
index ed4edea..d6818b3 100644
--- a/docs/socketexample.rst
+++ b/docs/socketexample.rst
@@ -5,7 +5,7 @@ The component architecture provides an application framework that provides its
functionality through loosely-connected components. A *component* can be any
Python object and has a particular purpose associated with it. Thus, in a
component-based applications you have many small component in contrast to
-classical object-oriented development, where you have a few big objects.
+classical object-oriented development, where you have a few big objects.
Components communicate via specific APIs, which are formally defined by
interfaces, which are provided by the `zope.interface` package. *Interfaces*
@@ -43,7 +43,7 @@ So let's say that we have a German socket:
.. doctest::
- >>> from zope.interface import Interface, implements
+ >>> from zope.interface import Interface, implementer
>>> class IGermanSocket(Interface):
... pass
@@ -52,9 +52,9 @@ So let's say that we have a German socket:
... def __repr__(self):
... return '<instance of %s>' %self.__class__.__name__
- >>> class GermanSocket(Socket):
+ >>> @implementer(IGermanSocket)
+ ... class GermanSocket(Socket):
... """German wall socket."""
- ... implements(IGermanSocket)
and we want to convert it to an US socket
@@ -68,10 +68,10 @@ store to look for an adapter that we can plug in the wall:
.. doctest::
- >>> class GermanToUSSocketAdapter(Socket):
- ... implements(IUSSocket)
+ >>> @implementer(IUSSocket)
+ ... class GermanToUSSocketAdapter(Socket):
... __used_for__ = IGermanSocket
- ...
+ ...
... def __init__(self, socket):
... self.context = socket
@@ -118,7 +118,7 @@ so that the socket now provides the US version:
>>> IUSSocket.providedBy(bathroomUS)
True
-Now you can insert your shaver and get on with your day.
+Now you can insert your shaver and get on with your day.
After a week you travel for a couple of days to the Prague and you notice that
the Czech have yet another socket type:
@@ -128,8 +128,9 @@ the Czech have yet another socket type:
>>> class ICzechSocket(Interface):
... pass
- >>> class CzechSocket(Socket):
- ... implements(ICzechSocket)
+ >>> @implementer(ICzechSocket)
+ ... class CzechSocket(Socket):
+ ... pass
>>> czech = CzechSocket()
@@ -142,7 +143,7 @@ you do not have one:
... #doctest: +NORMALIZE_WHITESPACE
Traceback (most recent call last):
...
- ComponentLookupError: (<instance of CzechSocket>,
+ ComponentLookupError: (<instance of CzechSocket>,
<InterfaceClass __builtin__.IUSSocket>,
'')
@@ -171,10 +172,10 @@ frequency of the AC current:
.. doctest::
- >>> class GermanToUSSocketAdapterAndTransformer(object):
- ... implements(IUSSocket)
+ >>> @implementer(IUSSocket)
+ ... class GermanToUSSocketAdapterAndTransformer(object):
... __used_for__ = IGermanSocket
- ...
+ ...
... def __init__(self, socket):
... self.context = socket
@@ -208,7 +209,7 @@ Clearly, we do not have an adapter for the MP3 player
... #doctest: +NORMALIZE_WHITESPACE
Traceback (most recent call last):
...
- ComponentLookupError: (<instance of GermanSocket>,
+ ComponentLookupError: (<instance of GermanSocket>,
<InterfaceClass __builtin__.IUSSocket>,
'mp3')
@@ -222,15 +223,26 @@ to know about all the adapters that convert a German to a US socket type:
>>> sockets = list(zope.component.getAdapters((bathroomDE,), IUSSocket))
>>> len(sockets)
3
- >>> names = [name for name, socket in sockets]
- >>> names.sort()
+ >>> names = sorted([str(name) for name, socket in sockets])
>>> names
- [u'', u'dvd', u'shaver']
+ ['', 'dvd', 'shaver']
-`zope.component.getAdapters()` returns a list of tuples. The first
+:func:`zope.component.getAdapters` returns a list of tuples. The first
entry of the tuple is the name of the adapter and the second is the
adapter itself.
+Note that the names are ``unicode`` on Python 2:
+
+.. doctest::
+
+ >>> try:
+ ... unicode = unicode
+ ... except NameError:
+ ... unicode = str
+ >>> [isinstance(name, unicode) for name, _ in sockets]
+ [True, True, True]
+
+
Multi-Adapters
~~~~~~~~~~~~~~
@@ -253,8 +265,8 @@ buy yet another adapter, but a piece that provides the grounding plug:
>>> class IGrounder(Interface):
... pass
- >>> class Grounder(object):
- ... implements(IGrounder)
+ >>> @implementer(IGrounder)
+ ... class Grounder(object):
... def __repr__(self):
... return '<instance of Grounder>'
@@ -263,8 +275,8 @@ Then together they will provided a grounded us socket:
.. doctest::
- >>> class GroundedGermanToUSSocketAdapter(object):
- ... implements(IUSGroundedSocket)
+ >>> @implementer(IUSGroundedSocket)
+ ... class GroundedGermanToUSSocketAdapter(object):
... __used_for__ = (IGermanSocket, IGrounder)
... def __init__(self, socket, grounder):
... self.socket, self.grounder = socket, grounder
@@ -293,7 +305,7 @@ we can now get a grounded US socket:
.. doctest::
- >>> socket = zope.component.getMultiAdapter((livingroom, grounder),
+ >>> socket = zope.component.getMultiAdapter((livingroom, grounder),
... IUSGroundedSocket, 'mp3')
.. doctest::
@@ -314,8 +326,8 @@ Of course, you do not have a 'dvd' grounded US socket available:
... #doctest: +NORMALIZE_WHITESPACE
Traceback (most recent call last):
...
- ComponentLookupError: ((<instance of GermanSocket>,
- <instance of Grounder>),
+ ComponentLookupError: ((<instance of GermanSocket>,
+ <instance of Grounder>),
<InterfaceClass __builtin__.IUSGroundedSocket>,
'dvd')
@@ -345,8 +357,9 @@ Let's say one of our adapters overheated and caused a small fire:
>>> class IFire(Interface):
... pass
- >>> class Fire(object):
- ... implements(IFire)
+ >>> @implementer(IFire)
+ ... class Fire(object):
+ ... pass
>>> fire = Fire()
@@ -358,12 +371,18 @@ We want to use all available objects to put out the fire:
... def extinguish():
... pass
- >>> class FireExtinguisher(object):
+ >>> from functools import total_ordering
+ >>> @total_ordering
+ ... class FireExtinguisher(object):
... def __init__(self, fire):
... pass
... def extinguish(self):
... "Place extinguish code here."
- ... print 'Used ' + self.__class__.__name__ + '.'
+ ... print('Used ' + self.__class__.__name__ + '.')
+ ... def __lt__(self, other):
+ ... return type(self).__name__ < type(other).__name__
+ ... def __eq__(self, other):
+ ... return self is other
Here some specific methods to put out the fire:
@@ -371,7 +390,7 @@ Here some specific methods to put out the fire:
>>> class PowderExtinguisher(FireExtinguisher):
... pass
- >>> gsm.registerSubscriptionAdapter(PowderExtinguisher,
+ >>> gsm.registerSubscriptionAdapter(PowderExtinguisher,
... (IFire,), IFireExtinguisher)
>>> class Blanket(FireExtinguisher):
@@ -396,7 +415,7 @@ Now let use all these things to put out the fire:
Used SprinklerSystem.
If no subscribers are found for a particular object, then an empty list is
-returned:
+returned:
.. doctest::
@@ -429,8 +448,8 @@ electric generator. The generator provides of course a US-style socket:
.. doctest::
- >>> class Generator(object):
- ... implements(IUSSocket)
+ >>> @implementer(IUSSocket)
+ ... class Generator(object):
... def __repr__(self):
... return '<instance of Generator>'
@@ -492,8 +511,8 @@ panels that provide a regular US-style socket as output:
.. doctest::
- >>> class SolarPanel(object):
- ... implements(IUSSocket)
+ >>> @implementer(IUSSocket)
+ ... class SolarPanel(object):
... def __repr__(self):
... return '<instance of Solar Panel>'
@@ -537,11 +556,9 @@ following API function will return a list of name/utility pairs:
.. doctest::
- >>> utils = list(zope.component.getUtilitiesFor(IUSSocket))
- >>> utils.sort()
- >>> utils #doctest: +NORMALIZE_WHITESPACE
- [(u'', <instance of Generator>),
- (u'Solar Panel', <instance of Solar Panel>)]
+ >>> utils = sorted(list(zope.component.getUtilitiesFor(IUSSocket)))
+ >>> [(str(name), socket) for name, socket in utils]
+ [('', <instance of Generator>), ('Solar Panel', <instance of Solar Panel>)]
Another method of looking up all utilities is by using
`getAllUtilitiesRegisteredFor(iface)`. This function will return an iterable
@@ -552,7 +569,7 @@ need this method.
.. doctest::
>>> utils = list(zope.component.getAllUtilitiesRegisteredFor(IUSSocket))
- >>> utils.sort()
+ >>> utils.sort(key=lambda x: type(x).__name__)
>>> utils
[<instance of Generator>, <instance of Solar Panel>]
@@ -577,7 +594,7 @@ the solar panel. To do this, we can use a standard implementation of the
.. doctest::
>>> from zope.component.factory import Factory
- >>> factory = Factory(SolarPanel,
+ >>> factory = Factory(SolarPanel,
... 'Solar Panel',
... 'This factory creates a solar panel.')
@@ -631,11 +648,9 @@ providing a certain interface:
.. doctest::
>>> factories = zope.component.getFactoriesFor(IUSSocket)
- >>> factories = [(name, factory.__class__) for name, factory in factories]
- >>> factories.sort()
- >>> factories #doctest: +NORMALIZE_WHITESPACE
- [(u'Generator', <class 'zope.component.factory.Factory'>),
- (u'SolarPanel', <class 'zope.component.factory.Factory'>)]
+ >>> factories = sorted([(name, factory.__class__) for name, factory in factories])
+ >>> [(str(name), kind) for name, kind in factories]
+ [('Generator', <class 'zope.component.factory.Factory'>), ('SolarPanel', <class 'zope.component.factory.Factory'>)]
Site Managers