Skip to content

Commit

Permalink
Enable doctests on Python 3 and PyPy
Browse files Browse the repository at this point in the history
  • Loading branch information
jamadden committed Jun 29, 2017
1 parent 04fbd49 commit 5c1df91
Show file tree
Hide file tree
Showing 12 changed files with 179 additions and 156 deletions.
7 changes: 2 additions & 5 deletions .travis.yml
Expand Up @@ -2,9 +2,6 @@ language: python
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:
Expand All @@ -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
- if [[ -z "$MINIMAL" ]]; sphinx-build -b html -d docs/_build/doctrees docs docs/_build/html; fi
- if [[ -z "$MINIMAL" ]]; coverage run `which sphinx-build` -b doctest -d docs/_build/doctrees docs docs/_build/doctest; fi

after_success:
- coveralls
Expand Down
17 changes: 11 additions & 6 deletions docs/api/adapter.rst
Expand Up @@ -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.
Expand All @@ -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
Expand All @@ -402,4 +408,3 @@ Helpers for Declaring / Testing Adapters

from zope.component.testing import tearDown
tearDown()

6 changes: 3 additions & 3 deletions docs/api/interface.rst
Expand Up @@ -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
Expand Down Expand Up @@ -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::

Expand Down
6 changes: 3 additions & 3 deletions docs/api/persistent.rst
Expand Up @@ -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
Expand Down
9 changes: 5 additions & 4 deletions docs/event.rst
Expand Up @@ -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:

Expand All @@ -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:

Expand Down
35 changes: 17 additions & 18 deletions docs/factory.rst
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand All @@ -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')
Expand All @@ -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'>)]
13 changes: 6 additions & 7 deletions docs/hooks.rst
Expand Up @@ -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
Expand Down Expand Up @@ -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>
Expand All @@ -86,27 +86,26 @@ 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
raises an exception:

.. doctest::

>>> print getSite()
>>> print(getSite())
None
>>> with zope.component.hooks.site(site2):
... getSite() is site2
... raise ValueError('An error in the body')
Traceback (most recent call last):
...
ValueError: An error in the body
>>> print getSite()
>>> print(getSite())
None

0 comments on commit 5c1df91

Please sign in to comment.