summaryrefslogtreecommitdiff
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 10:28:28 -0500
commit10497023dea16ce976621663ab1c458a100406fb (patch)
treeb3c75f229fcf122d299236243069dd0ef0b2833d
parent04fbd4917e1861e22ce612ca3f513b9dac03413d (diff)
downloadzope-component-doctest-everywhere.tar.gz
Enable doctests on Python 3 and PyPydoctest-everywhere
-rw-r--r--.travis.yml7
-rw-r--r--docs/api/adapter.rst17
-rw-r--r--docs/api/interface.rst6
-rw-r--r--docs/api/persistent.rst6
-rw-r--r--docs/event.rst9
-rw-r--r--docs/factory.rst35
-rw-r--r--docs/hooks.rst13
-rw-r--r--docs/narr.rst84
-rw-r--r--docs/socketexample.rst111
-rw-r--r--docs/testlayer.rst11
-rw-r--r--docs/zcml.rst34
11 files changed, 177 insertions, 156 deletions
diff --git a/.travis.yml b/.travis.yml
index 702504e..cf933aa 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -3,9 +3,6 @@ sudo: false
matrix:
include:
- python: 2.7
- env: DOCS=1
- # The doctests only run on Python 2.7
- - python: 2.7
env: MINIMAL="-t !persistentregistry -t !security"
python:
- 2.7
@@ -17,8 +14,8 @@ python:
script:
- coverage run -m zope.testrunner --test-path=src $MINIMAL
- - if [[ -n "$DOCS" ]]; then sphinx-build -b html -d docs/_build/doctrees docs docs/_build/html; fi
- - if [[ -n "$DOCS" ]]; then coverage run `which sphinx-build` -b doctest -d docs/_build/doctrees docs docs/_build/doctest; fi
+ - sphinx-build -b html -d docs/_build/doctrees docs docs/_build/html
+ - coverage run `which sphinx-build` -b doctest -d docs/_build/doctrees docs docs/_build/doctest
after_success:
- coveralls
diff --git a/docs/api/adapter.rst b/docs/api/adapter.rst
index 992d9e5..1cfeb8f 100644
--- a/docs/api/adapter.rst
+++ b/docs/api/adapter.rst
@@ -358,14 +358,20 @@ Let's register some adapters first:
>>> gsm.registerAdapter(Comp, [None], I5, 'foo')
Now we get all the adapters that are registered for ``ob`` that provide
-``I5``:
+``I5`` (note that on Python 2 the names will be ``unicode``):
.. doctest::
>>> from zope.component import getAdapters
>>> adapters = sorted(getAdapters((ob,), I5))
- >>> [(name, adapter.__class__.__name__) for name, adapter in adapters]
- [(u'', 'Comp'), (u'foo', 'Comp')]
+ >>> [(str(name), adapter.__class__.__name__) for name, adapter in adapters]
+ [('', 'Comp'), ('foo', 'Comp')]
+ >>> try:
+ ... unicode = unicode
+ ... except NameError:
+ ... unicode = str # Python 3
+ >>> [isinstance(name, unicode) for name, _ in adapters]
+ [True, True]
Note that the output doesn't include None values. If an adapter
factory returns None, it is as if it wasn't present.
@@ -374,8 +380,8 @@ factory returns None, it is as if it wasn't present.
>>> gsm.registerAdapter(lambda context: None, [I1], I5, 'nah')
>>> adapters = sorted(getAdapters((ob,), I5))
- >>> [(name, adapter.__class__.__name__) for name, adapter in adapters]
- [(u'', 'Comp'), (u'foo', 'Comp')]
+ >>> [(str(name), adapter.__class__.__name__) for name, adapter in adapters]
+ [('', 'Comp'), ('foo', 'Comp')]
Subscription Adapters
@@ -402,4 +408,3 @@ Helpers for Declaring / Testing Adapters
from zope.component.testing import tearDown
tearDown()
-
diff --git a/docs/api/interface.rst b/docs/api/interface.rst
index fbaf57f..ff456f7 100644
--- a/docs/api/interface.rst
+++ b/docs/api/interface.rst
@@ -115,7 +115,7 @@ We can register ``IDemo`` as providing more than one interface:
False
>>> queryInterface('zope.component.tests.examples.IQI') is None
True
-
+
>>> provideInterface('', IQI, ITestType)
>>> ITestType.providedBy(IQI)
True
@@ -175,8 +175,8 @@ We can register ``IDemo`` as providing more than one interface:
>>> provideInterface('', ISII, ITestType)
>>> ITestType.providedBy(ISII)
True
- >>> searchInterfaceIds(None, 'zope.component.tests.examples.ISII')
- [u'zope.component.tests.examples.ISII']
+ >>> [str(x) for x in searchInterfaceIds(None, 'zope.component.tests.examples.ISII')]
+ ['zope.component.tests.examples.ISII']
.. testcleanup::
diff --git a/docs/api/persistent.rst b/docs/api/persistent.rst
index 69c9e4b..eaad08f 100644
--- a/docs/api/persistent.rst
+++ b/docs/api/persistent.rst
@@ -167,11 +167,11 @@ We want to make sure that we see updates corrextly.
>>> import persistent
>>> import transaction
>>> from zope.interface import Interface
- >>> from zope.interface import implements
+ >>> from zope.interface import implementer
>>> class IFoo(Interface):
... pass
- >>> class Foo(persistent.Persistent):
- ... implements(IFoo)
+ >>> @implementer(IFoo)
+ ... class Foo(persistent.Persistent):
... name = ''
... def __init__(self, name=''):
... self.name = name
diff --git a/docs/event.rst b/docs/event.rst
index bc10e8d..bf87472 100644
--- a/docs/event.rst
+++ b/docs/event.rst
@@ -76,9 +76,10 @@ First create an object class:
>>> class IUseless(zope.interface.Interface):
... """Useless object"""
- >>> class UselessObject(object):
+ >>> @zope.interface.implementer(IUseless)
+ ... class UselessObject(object):
... """Useless object"""
- ... zope.interface.implements(IUseless)
+
Then create an event class:
@@ -87,9 +88,9 @@ Then create an event class:
>>> class IObjectThrownEvent(zope.component.interfaces.IObjectEvent):
... """An object has been thrown away"""
- >>> class ObjectThrownEvent(zope.component.interfaces.ObjectEvent):
+ >>> @zope.interface.implementer(IObjectThrownEvent)
+ ... class ObjectThrownEvent(zope.component.interfaces.ObjectEvent):
... """An object has been thrown away"""
- ... zope.interface.implements(IObjectThrownEvent)
Create an object and an event:
diff --git a/docs/factory.rst b/docs/factory.rst
index 3e90856..d957da3 100644
--- a/docs/factory.rst
+++ b/docs/factory.rst
@@ -14,10 +14,10 @@ The Factory Class
>>> class IKlass(Interface):
... pass
- >>> from zope.interface import implements
- >>> class Klass(object):
- ... implements(IKlass)
- ...
+ >>> from zope.interface import implementer
+ >>> @implementer(IKlass)
+ ... class Klass(object):
+ ...
... def __init__(self, *args, **kw): #*
... self.args = args
... self.kw = kw
@@ -53,14 +53,14 @@ and make sure that the correct class was used to create the object:
<class 'Klass'>
Since we passed in a couple positional and a keyword argument
-
+
.. doctest::
>>> kl.args
(1, 2)
>>> kl.kw
{'foo': 3}
-
+
>>> factory2(3)
3
>>> factory3(3)
@@ -94,16 +94,16 @@ Provided Interfaces
>>> implemented = factory.getInterfaces()
>>> implemented.isOrExtends(IKlass)
True
- >>> list(implemented)
- [<InterfaceClass __builtin__.IKlass>]
-
+ >>> list(implemented) == [IKlass]
+ True
+
>>> implemented2 = factory2.getInterfaces()
>>> list(implemented2)
[]
-
+
>>> implemented3 = factory3.getInterfaces()
- >>> list(implemented3)
- [<InterfaceClass __builtin__.IFunction>]
+ >>> list(implemented3) == [IFunction]
+ True
The Component Architecture Factory API
@@ -113,7 +113,7 @@ The Component Architecture Factory API
>>> import zope.component
>>> factory = Factory(Klass, 'Klass', 'Klassier')
- >>> gsm = zope.component.getGlobalSiteManager()
+ >>> gsm = zope.component.getGlobalSiteManager()
>>> from zope.component.interfaces import IFactory
>>> gsm.registerUtility(factory, IFactory, 'klass')
@@ -139,15 +139,14 @@ Accessing Provided Interfaces
>>> implemented = zope.component.getFactoryInterfaces('klass')
>>> implemented.isOrExtends(IKlass)
True
- >>> [iface for iface in implemented]
- [<InterfaceClass __builtin__.IKlass>]
+ >>> [iface for iface in implemented] == [IKlass]
+ True
List of All Factories
~~~~~~~~~~~~~~~~~~~~~
.. doctest::
- >>> [(name, fac.__class__) for name, fac in
+ >>> [(str(name), fac.__class__) for name, fac in
... zope.component.getFactoriesFor(IKlass)]
- [(u'klass', <class 'zope.component.factory.Factory'>)]
-
+ [('klass', <class 'zope.component.factory.Factory'>)]
diff --git a/docs/hooks.rst b/docs/hooks.rst
index 76fc6fd..713d12f 100644
--- a/docs/hooks.rst
+++ b/docs/hooks.rst
@@ -14,7 +14,7 @@ As long as we haven't set a site, none is being considered current:
.. doctest::
>>> from zope.component.hooks import getSite
- >>> print getSite()
+ >>> print(getSite())
None
We can also ask for the current component registry (aka site manager
@@ -71,7 +71,7 @@ Finally we can unset the site and the global component registry is used again:
.. doctest::
>>> setSite()
- >>> print getSite()
+ >>> print(getSite())
None
>>> getSiteManager()
<BaseGlobalComponents base>
@@ -86,12 +86,12 @@ useful when writing tests:
.. doctest::
>>> import zope.component.hooks
- >>> print getSite()
+ >>> print(getSite())
None
>>> with zope.component.hooks.site(site2):
... getSite() is site2
True
- >>> print getSite()
+ >>> print(getSite())
None
The site is properly restored even if the body of the with statement
@@ -99,7 +99,7 @@ raises an exception:
.. doctest::
- >>> print getSite()
+ >>> print(getSite())
None
>>> with zope.component.hooks.site(site2):
... getSite() is site2
@@ -107,6 +107,5 @@ raises an exception:
Traceback (most recent call last):
...
ValueError: An error in the body
- >>> print getSite()
+ >>> print(getSite())
None
-
diff --git a/docs/narr.rst b/docs/narr.rst
index ddc1de9..a1b7469 100644
--- a/docs/narr.rst
+++ b/docs/narr.rst
@@ -1,6 +1,8 @@
Zope Component Architecture
===========================
+.. currentmodule:: zope.component
+
This package, together with `zope.interface`, provides facilities for
defining, registering and looking up components. There are two basic
kinds of components: adapters and utilities.
@@ -14,22 +16,23 @@ definition:
.. doctest::
+ >>> from __future__ import print_function
>>> from zope import interface
>>> class IGreeter(interface.Interface):
... def greet():
... "say hello"
- >>> class Greeter:
- ... interface.implements(IGreeter)
+ >>> @interface.implementer(IGreeter)
+ ... class Greeter(object):
...
... def __init__(self, other="world"):
... self.other = other
...
... def greet(self):
- ... print "Hello", self.other
+ ... print(("Hello %s" % (self.other)))
-We can register an instance this class using `provideUtility` [1]_:
+We can register an instance this class using :func:`provideUtility` [1]_:
.. doctest::
@@ -37,9 +40,9 @@ We can register an instance this class using `provideUtility` [1]_:
>>> greet = Greeter('bob')
>>> component.provideUtility(greet, IGreeter, 'robert')
-In this example we registered the utility as providing the `IGreeter`
+In this example we registered the utility as providing the ``IGreeter``
interface with a name of 'bob'. We can look the interface up with
-either `queryUtility` or `getUtility`:
+either :func:`queryUtility` or :func:`getUtility`:
.. doctest::
@@ -49,7 +52,7 @@ either `queryUtility` or `getUtility`:
>>> component.getUtility(IGreeter, 'robert').greet()
Hello bob
-`queryUtility` and `getUtility` differ in how failed lookups are handled:
+:func:`queryUtility` and :func:`getUtility` differ in how failed lookups are handled:
.. doctest::
@@ -63,7 +66,7 @@ either `queryUtility` or `getUtility`:
ComponentLookupError: (<InterfaceClass ...IGreeter>, 'ted')
If a component provides only one interface, as in the example above,
-then we can omit the provided interface from the call to `provideUtility`:
+then we can omit the provided interface from the call to :func:`provideUtility`:
.. doctest::
@@ -95,21 +98,20 @@ for different people:
>>> class IPerson(interface.Interface):
... name = interface.Attribute("Name")
- >>> class PersonGreeter:
- ...
- ... component.adapts(IPerson)
- ... interface.implements(IGreeter)
+ >>> @component.adapter(IPerson)
+ ... @interface.implementer(IGreeter)
+ ... class PersonGreeter(object):
...
... def __init__(self, person):
... self.person = person
...
... def greet(self):
- ... print "Hello", self.person.name
+ ... print("Hello", self.person.name)
The class defines a constructor that takes an argument for every
object adapted.
-We used `component.adapts` to declare what we adapt. We can find
+We used :func:`adapter` to declare what we adapt. We can find
out if an object declares that it adapts anything using adaptedBy:
.. doctest::
@@ -139,8 +141,8 @@ interface:
.. doctest::
- >>> class Person:
- ... interface.implements(IPerson)
+ >>> @interface.implementer(IPerson)
+ ... class Person(object):
...
... def __init__(self, name):
... self.name = name
@@ -156,7 +158,7 @@ how to register the adapter.
>>> class BobPersonGreeter(PersonGreeter):
... name = 'Bob'
... def greet(self):
- ... print "Hello", self.person.name, "my name is", self.name
+ ... print("Hello", self.person.name, "my name is", self.name)
>>> component.provideAdapter(
... BobPersonGreeter, [IPerson], IGreeter, 'bob')
@@ -172,7 +174,7 @@ The arguments can also be provided as keyword arguments:
... factory=TedPersonGreeter, adapts=[IPerson],
... provides=IGreeter, name='ted')
-For named adapters, use `queryAdapter`, or `getAdapter`:
+For named adapters, use :func:`queryAdapter`, or :func:`getAdapter`:
.. doctest::
@@ -182,8 +184,8 @@ For named adapters, use `queryAdapter`, or `getAdapter`:
>>> component.getAdapter(Person("Sally"), IGreeter, 'ted').greet()
Hello Sally my name is Ted
-If an adapter can't be found, `queryAdapter` returns a default value
-and `getAdapter` raises an error:
+If an adapter can't be found, :func:`queryAdapter` returns a default value
+and :func:`getAdapter` raises an error:
.. doctest::
@@ -200,18 +202,17 @@ Adapters can adapt multiple objects:
.. doctest::
- >>> class TwoPersonGreeter:
- ...
- ... component.adapts(IPerson, IPerson)
- ... interface.implements(IGreeter)
+ >>> @component.adapter(IPerson, IPerson)
+ ... @interface.implementer(IGreeter)
+ ... class TwoPersonGreeter(object):
...
... def __init__(self, person, greeter):
... self.person = person
... self.greeter = greeter
...
... def greet(self):
- ... print "Hello", self.person.name
- ... print "my name is", self.greeter.name
+ ... print("Hello", self.person.name)
+ ... print("my name is", self.greeter.name)
>>> component.provideAdapter(TwoPersonGreeter)
@@ -221,8 +222,8 @@ parameters given to the adapter and used to query the adapter. This is
especially the case when different Interfaces are adapt to (opposed to
this example).
-To look up a multi-adapter, use either `queryMultiAdapter` or
-`getMultiAdapter`:
+To look up a multi-adapter, use either :func:`queryMultiAdapter` or
+:func:`getMultiAdapter`:
.. doctest::
@@ -250,7 +251,7 @@ adapter decorator to declare that a callable object adapts some interfaces
In this example, the personJob function simply returns the person's
-`job` attribute if present, or None if it's not present. An adapter
+``job`` attribute if present, or None if it's not present. An adapter
factory can return None to indicate that adaptation wasn't possible.
Let's register this adapter and try it out:
@@ -302,8 +303,8 @@ Perhaps we have documents:
... summary = interface.Attribute("Document summary")
... body = interface.Attribute("Document text")
- >>> class Document:
- ... interface.implements(IDocument)
+ >>> @interface.implementer(IDocument)
+ ... class Document(object):
... def __init__(self, summary, body):
... self.summary, self.body = summary, body
@@ -313,9 +314,9 @@ line:
.. doctest::
- >>> class SingleLineSummary:
- ... component.adapts(IDocument)
- ... interface.implements(IValidate)
+ >>> @component.adapter(IDocument)
+ ... @interface.implementer(IValidate)
+ ... class SingleLineSummary(object):
...
... def __init__(self, doc):
... self.doc = doc
@@ -330,10 +331,9 @@ Or we might require the body to be at least 1000 characters in length:
.. doctest::
- >>> class AdequateLength:
- ... component.adapts(IDocument)
- ... interface.implements(IValidate)
- ...
+ >>> @component.adapter(IDocument)
+ ... @interface.implementer(IValidate)
+ ... class AdequateLength(object):
... def __init__(self, doc):
... self.doc = doc
...
@@ -410,8 +410,8 @@ To register the subscriber above, we define a document-created event:
>>> class IDocumentCreated(interface.Interface):
... doc = interface.Attribute("The document that was created")
- >>> class DocumentCreated:
- ... interface.implements(IDocumentCreated)
+ >>> @interface.implementer(IDocumentCreated)
+ ... class DocumentCreated(object):
...
... def __init__(self, doc):
... self.doc = doc
@@ -424,7 +424,7 @@ We'll also change our handler definition to:
... def documentCreated(event):
... event.doc.created = datetime.datetime.utcnow()
-This marks the handler as an adapter of `IDocumentCreated` events.
+This marks the handler as an adapter of ``IDocumentCreated`` events.
Now we'll register the handler [1]_:
@@ -432,7 +432,7 @@ Now we'll register the handler [1]_:
>>> component.provideHandler(documentCreated)
-Now, if we can create an event and use the `handle` function to call
+Now, if we can create an event and use the :func:`handle` function to call
handlers registered for the event:
.. doctest::
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
diff --git a/docs/testlayer.rst b/docs/testlayer.rst
index 5388d51..98dc96c 100644
--- a/docs/testlayer.rst
+++ b/docs/testlayer.rst
@@ -21,16 +21,16 @@ own. We do this simply by subclassing:
>>> class OurLayer(LayerBase):
... def setUp(self):
... super(OurLayer, self).setUp()
- ... print "setUp called"
+ ... print("setUp called")
... def tearDown(self):
... super(OurLayer, self).tearDown()
- ... print "tearDown called"
+ ... print("tearDown called")
... def testSetUp(self):
... super(OurLayer, self).testSetUp()
- ... print "testSetUp called"
+ ... print("testSetUp called")
... def testTearDown(self):
... super(OurLayer, self).testTearDown()
- ... print "testTearDown called"
+ ... print("testTearDown called")
Note that if we wanted to ensure that the methods of the superclass
were called we have to use super(). In this case we actually wouldn't
@@ -54,7 +54,7 @@ Now we run some tests with this layer:
... layer = layer
...
... def testFoo(self):
- ... print "testFoo"
+ ... print("testFoo")
>>> suite = unittest.TestSuite()
>>> suite.addTest(unittest.makeSuite(TestCase))
>>> from zope.testrunner.runner import Runner
@@ -108,4 +108,3 @@ Since the ZCML sets up an adapter, we expect the tests to pass:
Ran 1 tests with 0 failures, 0 errors and 0 skipped in ... seconds.
Tearing down left over layers:
Tear down zope.component.testfiles.ZCMLFileLayer in ... seconds.
-
diff --git a/docs/zcml.rst b/docs/zcml.rst
index cb94284..9d0c5bc 100644
--- a/docs/zcml.rst
+++ b/docs/zcml.rst
@@ -15,7 +15,7 @@ This helper will let us easily execute ZCML snippets:
.. doctest::
- >>> from cStringIO import StringIO
+ >>> from io import BytesIO
>>> from zope.configuration.xmlconfig import xmlconfig
>>> def runSnippet(snippet):
... template = """\
@@ -23,7 +23,7 @@ This helper will let us easily execute ZCML snippets:
... i18n_domain="zope">
... %s
... </configure>"""
- ... xmlconfig(StringIO(template % snippet))
+ ... xmlconfig(BytesIO((template % snippet).encode("ascii")))
adapter
-------
@@ -225,8 +225,10 @@ instance of the ``Content`` class:
.. doctest::
>>> import zope.interface
- >>> class MyContent:
- ... zope.interface.implements(IContent)
+ >>> @zope.interface.implementer(IContent)
+ ... class MyContent(object):
+ ... pass
+
>>> zope.component.getAdapter(MyContent(), I1, '') # doctest: +ELLIPSIS
Traceback (most recent call last):
...
@@ -495,7 +497,7 @@ adapter:
>>> p = ProxyFactory(ob)
>>> a = I1(p)
>>> type(a)
- <type 'zope.security._proxy._Proxy'>
+ <... 'zope.security._proxy._Proxy'>
While the adapter is security-proxied, the object it adapts is now
proxy-free. The adapter has umlimited access to it:
@@ -544,7 +546,7 @@ adapter:
>>> p = ProxyFactory(ob)
>>> a = I1(p)
>>> type(a)
- <type 'zope.security._proxy._Proxy'>
+ <... 'zope.security._proxy._Proxy'>
Since we protected the adapter with a permission, we now encounter a
location proxy behind the security proxy:
@@ -576,7 +578,7 @@ permission (``zope.Public``), there will be no location proxy:
>>> p = ProxyFactory(ob)
>>> a = I1(p)
>>> type(a)
- <type 'zope.security._proxy._Proxy'>
+ <... 'zope.security._proxy._Proxy'>
>>> a = removeSecurityProxy(a)
>>> type(a) is A1
@@ -601,7 +603,7 @@ get location proxies:
>>> p = ProxyFactory(ob)
>>> a = I1(p)
>>> type(a)
- <type 'zope.security._proxy._Proxy'>
+ <... 'zope.security._proxy._Proxy'>
>>> a = removeSecurityProxy(a)
>>> type(a)
@@ -614,7 +616,7 @@ subscriber
With the <subscriber /> directive you can register subscription
adapters or event subscribers with the adapter registry. Consider
this very typical example of a <subscriber /> directive:
-
+
.. doctest::
>>> clearZCML()
@@ -644,7 +646,7 @@ components, such as the ZCML filename and line numbers:
>>> sm = zope.component.getSiteManager()
>>> doc = [reg.info for reg in sm.registeredSubscriptionAdapters()
... if reg.provided is IS][0]
- >>> print doc
+ >>> print(doc)
File "<string>", line 4.2-9.8
Could not read source.
@@ -818,7 +820,7 @@ unproxied access to it, but the subscriber itself is proxied:
>>> p = ProxyFactory(content)
>>> a3 = zope.component.subscribers((p, a1), IS)[0]
>>> type(a3)
- <type 'zope.security._proxy._Proxy'>
+ <... 'zope.security._proxy._Proxy'>
There's no location proxy behind the security proxy:
@@ -866,7 +868,7 @@ With a proxied object, we again get a security-proxied subscriber:
>>> a3 = zope.component.subscribers((p, a1), IS)[0]
>>> type(a3)
- <type 'zope.security._proxy._Proxy'>
+ <... 'zope.security._proxy._Proxy'>
>>> removeSecurityProxy(a3).context[0] is content
True
@@ -1129,6 +1131,10 @@ First we provide a stub configuration context:
.. doctest::
>>> import re, pprint
+ >>> try:
+ ... from cStringIO import StringIO
+ ... except ImportError:
+ ... from io import StringIO
>>> atre = re.compile(' at [0-9a-fA-Fx]+')
>>> class Context(object):
... actions = ()
@@ -1139,7 +1145,7 @@ First we provide a stub configuration context:
... pprinter = pprint.PrettyPrinter(stream=stream, width=60)
... pprinter.pprint(self.actions)
... r = stream.getvalue()
- ... return (''.join(atre.split(r))).strip()
+ ... return (u''.join(atre.split(r))).strip()
>>> context = Context()
Then we provide a test interface that we'd like to register:
@@ -1168,7 +1174,7 @@ However, after calling the directive handler...
((None,
<function provideInterface>,
('',
- <InterfaceClass __builtin__.I>,
+ <InterfaceClass ....I>,
<InterfaceClass zope.component.tests.examples.ITestType>)),)
...it does provide ``ITestType``: