summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Madden <jamadden@gmail.com>2018-09-27 07:11:23 -0500
committerJason Madden <jamadden@gmail.com>2018-09-27 07:11:23 -0500
commite93f66b15cc0ebfe667da0d7e08e1621c931f437 (patch)
tree9f5ef0362adffffe6d82b7bd51d81be91f1b4021
parentee3c202b62ca09fda23a5d02ab7ae8118b8f6635 (diff)
downloadzope-configuration-e93f66b15cc0ebfe667da0d7e08e1621c931f437.tar.gz
Unify docs for fields.rst/py back into .py
-rw-r--r--docs/api/fields.rst352
-rw-r--r--docs/conf.py7
-rw-r--r--src/zope/configuration/fields.py361
-rw-r--r--src/zope/configuration/tests/test_docs.py34
4 files changed, 377 insertions, 377 deletions
diff --git a/docs/api/fields.rst b/docs/api/fields.rst
index c44dcf1..b640a30 100644
--- a/docs/api/fields.rst
+++ b/docs/api/fields.rst
@@ -1,349 +1,5 @@
-:mod:`zope.configuration.fields`
-================================
+===========================
+ zope.configuration.fields
+===========================
-.. module:: zope.configuration.fields
-
-.. autoclass:: PythonIdentifier
- :members:
- :member-order: bysource
-
- Let's look at an example:
-
- .. doctest::
-
- >>> from zope.configuration.fields import PythonIdentifier
- >>> class FauxContext(object):
- ... pass
- >>> context = FauxContext()
- >>> field = PythonIdentifier().bind(context)
-
- Let's test the fromUnicode method:
-
- .. doctest::
-
- >>> field.fromUnicode(u'foo')
- 'foo'
- >>> field.fromUnicode(u'foo3')
- 'foo3'
- >>> field.fromUnicode(u'_foo3')
- '_foo3'
-
- Now let's see whether validation works alright
-
- .. doctest::
-
- >>> for value in (u'foo', u'foo3', u'foo_', u'_foo3', u'foo_3', u'foo3_'):
- ... _ = field.fromUnicode(value)
- >>> from zope.schema import ValidationError
- >>> for value in (u'3foo', u'foo:', u'\\', u''):
- ... try:
- ... field.fromUnicode(value)
- ... except ValidationError:
- ... print('Validation Error ' + repr(value))
- Validation Error '3foo'
- Validation Error 'foo:'
- Validation Error '\\'
- Validation Error ''
-
-.. autoclass:: GlobalObject
- :members:
- :member-order: bysource
-
- Let's look at an example:
-
- .. doctest::
-
- >>> d = {'x': 1, 'y': 42, 'z': 'zope'}
- >>> class fakeresolver(dict):
- ... def resolve(self, n):
- ... return self[n]
- >>> fake = fakeresolver(d)
-
- >>> from zope.schema import Int
- >>> from zope.configuration.fields import GlobalObject
- >>> g = GlobalObject(value_type=Int())
- >>> gg = g.bind(fake)
- >>> gg.fromUnicode("x")
- 1
- >>> gg.fromUnicode(" x \n ")
- 1
- >>> gg.fromUnicode("y")
- 42
- >>> gg.fromUnicode("z")
- Traceback (most recent call last):
- ...
- WrongType: ('zope', (<type 'int'>, <type 'long'>), '')
-
- >>> g = GlobalObject(constraint=lambda x: x%2 == 0)
- >>> gg = g.bind(fake)
- >>> gg.fromUnicode("x")
- Traceback (most recent call last):
- ...
- ConstraintNotSatisfied: 1
- >>> gg.fromUnicode("y")
- 42
- >>> g = GlobalObject()
- >>> gg = g.bind(fake)
- >>> print(gg.fromUnicode('*'))
- None
-
-.. autoclass:: GlobalInterface
- :members:
- :member-order: bysource
-
- Example:
-
- First, we need to set up a stub name resolver:
-
- .. doctest::
-
- >>> from zope.interface import Interface
- >>> class IFoo(Interface):
- ... pass
- >>> class Foo(object):
- ... pass
- >>> d = {'Foo': Foo, 'IFoo': IFoo}
- >>> class fakeresolver(dict):
- ... def resolve(self, n):
- ... return self[n]
- >>> fake = fakeresolver(d)
-
- Now verify constraints are checked correctly:
-
- .. doctest::
-
- >>> from zope.configuration.fields import GlobalInterface
- >>> g = GlobalInterface()
- >>> gg = g.bind(fake)
- >>> gg.fromUnicode('IFoo') is IFoo
- True
- >>> gg.fromUnicode(' IFoo ') is IFoo
- True
- >>> gg.fromUnicode('Foo')
- Traceback (most recent call last):
- ...
- NotAnInterface: (<class 'Foo'>, ...
-
-.. autoclass:: Tokens
- :members:
- :member-order: bysource
-
- Consider GlobalObject tokens:
-
- First, we need to set up a stub name resolver:
-
- .. doctest::
-
- >>> d = {'x': 1, 'y': 42, 'z': 'zope', 'x.y.x': 'foo'}
- >>> class fakeresolver(dict):
- ... def resolve(self, n):
- ... return self[n]
- >>> fake = fakeresolver(d)
-
- >>> from zope.configuration.fields import Tokens
- >>> from zope.configuration.fields import GlobalObject
- >>> g = Tokens(value_type=GlobalObject())
- >>> gg = g.bind(fake)
- >>> gg.fromUnicode(" \n x y z \n")
- [1, 42, 'zope']
-
- >>> from zope.schema import Int
- >>> g = Tokens(value_type=
- ... GlobalObject(value_type=
- ... Int(constraint=lambda x: x%2 == 0)))
- >>> gg = g.bind(fake)
- >>> gg.fromUnicode("x y")
- Traceback (most recent call last):
- ...
- InvalidToken: 1 in x y
-
- >>> gg.fromUnicode("z y")
- Traceback (most recent call last):
- ...
- InvalidToken: ('zope', (<type 'int'>, <type 'long'>), '') in z y
- >>> gg.fromUnicode("y y")
- [42, 42]
-
-.. autoclass:: Path
- :members:
- :member-order: bysource
-
- Let's look at an example:
-
- First, we need a "context" for the field that has a path
- function for converting relative path to an absolute path.
-
- We'll be careful to do this in an os-independent fashion.
-
- .. doctest::
-
- >>> from zope.configuration.fields import Path
- >>> class FauxContext(object):
- ... def path(self, p):
- ... return os.path.join(os.sep, 'faux', 'context', p)
- >>> context = FauxContext()
- >>> field = Path().bind(context)
-
- Lets try an absolute path first:
-
- .. doctest::
-
- >>> import os
- >>> p = os.path.join(os.sep, u'a', u'b')
- >>> n = field.fromUnicode(p)
- >>> n.split(os.sep)
- ['', 'a', 'b']
-
- This should also work with extra spaces around the path:
-
- .. doctest::
-
- >>> p = " \n %s \n\n " % p
- >>> n = field.fromUnicode(p)
- >>> n.split(os.sep)
- ['', 'a', 'b']
-
- Environment variables are expanded:
-
- .. doctest::
-
- >>> os.environ['path-test'] = '42'
- >>> with_env = os.path.join(os.sep, u'a', u'${path-test}')
- >>> n = field.fromUnicode(with_env)
- >>> n.split(os.sep)
- ['', 'a', '42']
-
- Now try a relative path:
-
- .. doctest::
-
- >>> p = os.path.join(u'a', u'b')
- >>> n = field.fromUnicode(p)
- >>> n.split(os.sep)
- ['', 'faux', 'context', 'a', 'b']
-
- The current user is expanded (these are implicitly relative paths):
-
- .. doctest::
-
- >>> old_home = os.environ.get('HOME')
- >>> os.environ['HOME'] = os.path.join(os.sep, 'HOME')
- >>> n = field.fromUnicode('~')
- >>> n.split(os.sep)
- ['', 'HOME']
- >>> if old_home:
- ... os.environ['HOME'] = old_home
- ... else:
- ... del os.environ['HOME']
-
-
-.. autoclass:: Bool
- :members:
- :member-order: bysource
-
- .. doctest::
-
- >>> from zope.configuration.fields import Bool
- >>> Bool().fromUnicode(u"yes")
- True
- >>> Bool().fromUnicode(u"y")
- True
- >>> Bool().fromUnicode(u"true")
- True
- >>> Bool().fromUnicode(u"no")
- False
-
-.. autoclass:: MessageID
- :members:
- :member-order: bysource
-
- .. doctest::
-
- >>> from zope.configuration.fields import MessageID
- >>> class Info(object):
- ... file = 'file location'
- ... line = 8
- >>> class FauxContext(object):
- ... i18n_strings = {}
- ... info = Info()
- >>> context = FauxContext()
- >>> field = MessageID().bind(context)
-
- There is a fallback domain when no domain has been specified.
-
- Exchange the warn function so we can make test whether the warning
- has been issued
-
- .. doctest::
-
- >>> warned = None
- >>> def fakewarn(*args, **kw): #* syntax highlighting
- ... global warned
- ... warned = args
-
- >>> import warnings
- >>> realwarn = warnings.warn
- >>> warnings.warn = fakewarn
-
- >>> i = field.fromUnicode(u"Hello world!")
- >>> i
- 'Hello world!'
- >>> i.domain
- 'untranslated'
- >>> warned
- ("You did not specify an i18n translation domain for the '' field in file location",)
-
- >>> warnings.warn = realwarn
-
- With the domain specified:
-
- .. doctest::
-
- >>> context.i18n_strings = {}
- >>> context.i18n_domain = 'testing'
-
- We can get a message id:
-
- .. doctest::
-
- >>> i = field.fromUnicode(u"Hello world!")
- >>> i
- 'Hello world!'
- >>> i.domain
- 'testing'
-
- In addition, the string has been registered with the context:
-
- .. doctest::
-
- >>> context.i18n_strings
- {'testing': {'Hello world!': [('file location', 8)]}}
-
- >>> i = field.fromUnicode(u"Foo Bar")
- >>> i = field.fromUnicode(u"Hello world!")
- >>> from pprint import PrettyPrinter
- >>> pprint=PrettyPrinter(width=70).pprint
- >>> pprint(context.i18n_strings)
- {'testing': {'Foo Bar': [('file location', 8)],
- 'Hello world!': [('file location', 8),
- ('file location', 8)]}}
-
- >>> from zope.i18nmessageid import Message
- >>> isinstance(list(context.i18n_strings['testing'].keys())[0], Message)
- True
-
- Explicit Message IDs
-
- .. doctest::
-
- >>> i = field.fromUnicode(u'[View-Permission] View')
- >>> i
- 'View-Permission'
- >>> i.default
- 'View'
-
- >>> i = field.fromUnicode(u'[] [Some] text')
- >>> i
- '[Some] text'
- >>> i.default is None
- True
+.. automodule:: zope.configuration.fields
diff --git a/docs/conf.py b/docs/conf.py
index 9fffd20..ac65d4b 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -257,6 +257,7 @@ intersphinx_mapping = {
'https://zopeschema.readthedocs.io/en/latest': None,
}
-autodoc_default_flags = ['members', 'show-inheritance']
-autoclass_content = 'both'
-autodoc_member_order = 'bysource'
+autodoc_default_flags = [
+ 'members',
+ 'show-inheritance',
+]
diff --git a/src/zope/configuration/fields.py b/src/zope/configuration/fields.py
index 668c4a3..85a5ff7 100644
--- a/src/zope/configuration/fields.py
+++ b/src/zope/configuration/fields.py
@@ -33,13 +33,13 @@ from zope.configuration.exceptions import ConfigurationError
from zope.configuration.interfaces import InvalidToken
__all__ = [
- 'PythonIdentifier',
+ 'Bool',
'GlobalObject',
'GlobalInterface',
- 'Tokens',
- 'Path',
- 'Bool',
'MessageID',
+ 'Path',
+ 'PythonIdentifier',
+ 'Tokens',
]
@@ -47,6 +47,39 @@ class PythonIdentifier(schema_PythonIdentifier):
"""
This class is like `zope.schema.PythonIdentifier`.
+
+ Let's look at an example:
+
+ >>> from zope.configuration.fields import PythonIdentifier
+ >>> class FauxContext(object):
+ ... pass
+ >>> context = FauxContext()
+ >>> field = PythonIdentifier().bind(context)
+
+ Let's test the fromUnicode method:
+
+ >>> field.fromUnicode(u'foo')
+ 'foo'
+ >>> field.fromUnicode(u'foo3')
+ 'foo3'
+ >>> field.fromUnicode(u'_foo3')
+ '_foo3'
+
+ Now let's see whether validation works alright
+
+ >>> for value in (u'foo', u'foo3', u'foo_', u'_foo3', u'foo_3', u'foo3_'):
+ ... _ = field.fromUnicode(value)
+ >>> from zope.schema import ValidationError
+ >>> for value in (u'3foo', u'foo:', u'\\\\', u''):
+ ... try:
+ ... field.fromUnicode(value)
+ ... except ValidationError:
+ ... print('Validation Error ' + repr(value))
+ Validation Error '3foo'
+ Validation Error 'foo:'
+ Validation Error '\\\\'
+ Validation Error ''
+
.. versionchanged:: 4.2.0
Extend `zope.schema.PythonIdentifier`, which implies that `fromUnicode`
validates the strings.
@@ -79,6 +112,43 @@ class GlobalObject(Field):
self.value_type.validate(value)
def fromUnicode(self, value):
+ """
+ Find and return the module global at the path *value*.
+
+ >>> d = {'x': 1, 'y': 42, 'z': 'zope'}
+ >>> class fakeresolver(dict):
+ ... def resolve(self, n):
+ ... return self[n]
+ >>> fake = fakeresolver(d)
+
+ >>> from zope.schema import Int
+ >>> from zope.configuration.fields import GlobalObject
+ >>> g = GlobalObject(value_type=Int())
+ >>> gg = g.bind(fake)
+ >>> gg.fromUnicode("x")
+ 1
+ >>> gg.fromUnicode(" x \\n ")
+ 1
+ >>> gg.fromUnicode("y")
+ 42
+ >>> gg.fromUnicode("z")
+ Traceback (most recent call last):
+ ...
+ WrongType: ('zope', (<type 'int'>, <type 'long'>), '')
+
+ >>> g = GlobalObject(constraint=lambda x: x%2 == 0)
+ >>> gg = g.bind(fake)
+ >>> gg.fromUnicode("x")
+ Traceback (most recent call last):
+ ...
+ ConstraintNotSatisfied: 1
+ >>> gg.fromUnicode("y")
+ 42
+ >>> g = GlobalObject()
+ >>> gg = g.bind(fake)
+ >>> print(gg.fromUnicode('*'))
+ None
+ """
name = str(value.strip())
# special case, mostly for interfaces
@@ -108,7 +178,38 @@ class GlobalObject(Field):
@implementer(IFromUnicode)
class GlobalInterface(GlobalObject):
- """An interface that can be accessed from a module.
+ """
+ An interface that can be accessed from a module.
+
+ Example:
+
+ First, we need to set up a stub name resolver:
+
+ >>> from zope.interface import Interface
+ >>> class IFoo(Interface):
+ ... pass
+ >>> class Foo(object):
+ ... pass
+ >>> d = {'Foo': Foo, 'IFoo': IFoo}
+ >>> class fakeresolver(dict):
+ ... def resolve(self, n):
+ ... return self[n]
+ >>> fake = fakeresolver(d)
+
+ Now verify constraints are checked correctly:
+
+ >>> from zope.configuration.fields import GlobalInterface
+ >>> g = GlobalInterface()
+ >>> gg = g.bind(fake)
+ >>> gg.fromUnicode('IFoo') is IFoo
+ True
+ >>> gg.fromUnicode(' IFoo ') is IFoo
+ True
+ >>> gg.fromUnicode('Foo')
+ Traceback (most recent call last):
+ ...
+ NotAnInterface: (<class 'Foo'>, ...
+
"""
def __init__(self, **kw):
super(GlobalInterface, self).__init__(InterfaceField(), **kw)
@@ -116,18 +217,57 @@ class GlobalInterface(GlobalObject):
@implementer(IFromUnicode)
class Tokens(List):
- """A list that can be read from a space-separated string.
"""
- def fromUnicode(self, u):
- u = u.strip()
- if u:
+ A list that can be read from a space-separated string.
+ """
+
+ def fromUnicode(self, value):
+ """
+ Split the input string and convert it to *value_type*.
+
+ Consider GlobalObject tokens:
+
+ First, we need to set up a stub name resolver:
+
+ >>> d = {'x': 1, 'y': 42, 'z': 'zope', 'x.y.x': 'foo'}
+ >>> class fakeresolver(dict):
+ ... def resolve(self, n):
+ ... return self[n]
+ >>> fake = fakeresolver(d)
+
+ >>> from zope.configuration.fields import Tokens
+ >>> from zope.configuration.fields import GlobalObject
+ >>> g = Tokens(value_type=GlobalObject())
+ >>> gg = g.bind(fake)
+ >>> gg.fromUnicode(" \\n x y z \\n")
+ [1, 42, 'zope']
+
+ >>> from zope.schema import Int
+ >>> g = Tokens(value_type=
+ ... GlobalObject(value_type=
+ ... Int(constraint=lambda x: x%2 == 0)))
+ >>> gg = g.bind(fake)
+ >>> gg.fromUnicode("x y")
+ Traceback (most recent call last):
+ ...
+ InvalidToken: 1 in x y
+
+ >>> gg.fromUnicode("z y")
+ Traceback (most recent call last):
+ ...
+ InvalidToken: ('zope', (<type 'int'>, <type 'long'>), '') in z y
+ >>> gg.fromUnicode("y y")
+ [42, 42]
+ """
+ value = value.strip()
+ if value:
vt = self.value_type.bind(self.context)
values = []
- for s in u.split():
+ for s in value.split():
try:
v = vt.fromUnicode(s)
- except ValidationError as v:
- raise InvalidToken("%s in %s" % (v, u)).with_field_and_value(self, s)
+ except ValidationError as ex:
+ raise InvalidToken("%s in %r" % (ex, value)).with_field_and_value(self, s)
else:
values.append(v)
else:
@@ -159,15 +299,76 @@ class PathProcessor(object):
@implementer(IFromUnicode)
class Path(Text):
- """A file path name, which may be input as a relative path
+ """
+ A file path name, which may be input as a relative path
Input paths are converted to absolute paths and normalized.
-
- .. versionchanged:: 4.2.0
- Start expanding home directories and environment variables.
"""
def fromUnicode(self, value):
+ """
+ Convert the input path to a normalized, absolute path.
+
+ Let's look at an example:
+
+ First, we need a "context" for the field that has a path
+ function for converting relative path to an absolute path.
+
+ We'll be careful to do this in an os-independent fashion.
+
+ >>> from zope.configuration.fields import Path
+ >>> class FauxContext(object):
+ ... def path(self, p):
+ ... return os.path.join(os.sep, 'faux', 'context', p)
+ >>> context = FauxContext()
+ >>> field = Path().bind(context)
+
+ Lets try an absolute path first:
+
+ >>> import os
+ >>> p = os.path.join(os.sep, u'a', u'b')
+ >>> n = field.fromUnicode(p)
+ >>> n.split(os.sep)
+ ['', 'a', 'b']
+
+ This should also work with extra spaces around the path:
+
+ >>> p = " \\n %s \\n\\n " % p
+ >>> n = field.fromUnicode(p)
+ >>> n.split(os.sep)
+ ['', 'a', 'b']
+
+ Environment variables are expanded:
+
+ >>> os.environ['path-test'] = '42'
+ >>> with_env = os.path.join(os.sep, u'a', u'${path-test}')
+ >>> n = field.fromUnicode(with_env)
+ >>> n.split(os.sep)
+ ['', 'a', '42']
+
+ Now try a relative path:
+
+ >>> p = os.path.join(u'a', u'b')
+ >>> n = field.fromUnicode(p)
+ >>> n.split(os.sep)
+ ['', 'faux', 'context', 'a', 'b']
+
+ The current user is expanded (these are implicitly relative paths):
+
+ >>> old_home = os.environ.get('HOME')
+ >>> os.environ['HOME'] = os.path.join(os.sep, 'HOME')
+ >>> n = field.fromUnicode('~')
+ >>> n.split(os.sep)
+ ['', 'HOME']
+ >>> if old_home:
+ ... os.environ['HOME'] = old_home
+ ... else:
+ ... del os.environ['HOME']
+
+
+ .. versionchanged:: 4.2.0
+ Start expanding home directories and environment variables.
+ """
filename, needs_processing = PathProcessor.expand(value)
if needs_processing:
filename = self.context.path(filename)
@@ -177,12 +378,46 @@ class Path(Text):
@implementer(IFromUnicode)
class Bool(schema_Bool):
- """A boolean value
+ """
+ A boolean value.
Values may be input (in upper or lower case) as any of:
- yes, no, y, n, true, false, t, or f.
+
+ - yes / no
+ - y / n
+ - true / false
+ - t / f
+
+ .. caution::
+
+ Do not confuse this with :class:`zope.schema.Bool`.
+ That class will only parse ``"True"`` and ``"true"`` as
+ `True` values. Any other value will silently be accepted as
+ `False`. This class raises a validation error for unrecognized
+ input.
+
"""
+
def fromUnicode(self, value):
+ """
+ Convert the input string to a boolean.
+
+ Example:
+
+ >>> from zope.configuration.fields import Bool
+ >>> Bool().fromUnicode(u"yes")
+ True
+ >>> Bool().fromUnicode(u"y")
+ True
+ >>> Bool().fromUnicode(u"true")
+ True
+ >>> Bool().fromUnicode(u"no")
+ False
+ >>> Bool().fromUnicode(u"surprise")
+ Traceback (most recent call last):
+ ...
+ zope.schema._bootstrapinterfaces.InvalidValue
+ """
value = value.lower()
if value in ('1', 'true', 'yes', 't', 'y'):
return True
@@ -195,15 +430,99 @@ class Bool(schema_Bool):
@implementer(IFromUnicode)
class MessageID(Text):
- """Text string that should be translated.
+ """
+ Text string that should be translated.
- When a string is converted to a message ID, it is also
- recorded in the context.
+ When a string is converted to a message ID, it is also recorded in
+ the context.
"""
__factories = {}
def fromUnicode(self, u):
+ """
+ Translate a string to a MessageID.
+
+ >>> from zope.configuration.fields import MessageID
+ >>> class Info(object):
+ ... file = 'file location'
+ ... line = 8
+ >>> class FauxContext(object):
+ ... i18n_strings = {}
+ ... info = Info()
+ >>> context = FauxContext()
+ >>> field = MessageID().bind(context)
+
+ There is a fallback domain when no domain has been specified.
+
+ Exchange the warn function so we can make test whether the warning
+ has been issued
+
+ >>> warned = None
+ >>> def fakewarn(*args, **kw): #* syntax highlighting
+ ... global warned
+ ... warned = args
+
+ >>> import warnings
+ >>> realwarn = warnings.warn
+ >>> warnings.warn = fakewarn
+
+ >>> i = field.fromUnicode(u"Hello world!")
+ >>> i
+ 'Hello world!'
+ >>> i.domain
+ 'untranslated'
+ >>> warned
+ ("You did not specify an i18n translation domain for the '' field in file location",)
+
+ >>> warnings.warn = realwarn
+
+ With the domain specified:
+
+ >>> context.i18n_strings = {}
+ >>> context.i18n_domain = 'testing'
+
+ We can get a message id:
+
+ >>> i = field.fromUnicode(u"Hello world!")
+ >>> i
+ 'Hello world!'
+ >>> i.domain
+ 'testing'
+
+ In addition, the string has been registered with the context:
+
+ >>> context.i18n_strings
+ {'testing': {'Hello world!': [('file location', 8)]}}
+
+ >>> i = field.fromUnicode(u"Foo Bar")
+ >>> i = field.fromUnicode(u"Hello world!")
+ >>> from pprint import PrettyPrinter
+ >>> pprint=PrettyPrinter(width=70).pprint
+ >>> pprint(context.i18n_strings)
+ {'testing': {'Foo Bar': [('file location', 8)],
+ 'Hello world!': [('file location', 8),
+ ('file location', 8)]}}
+
+ >>> from zope.i18nmessageid import Message
+ >>> isinstance(list(context.i18n_strings['testing'].keys())[0], Message)
+ True
+
+ Explicit Message IDs
+
+ >>> i = field.fromUnicode(u'[View-Permission] View')
+ >>> i
+ 'View-Permission'
+ >>> i.default
+ 'View'
+
+ >>> i = field.fromUnicode(u'[] [Some] text')
+ >>> i
+ '[Some] text'
+ >>> i.default is None
+ True
+
+ """
context = self.context
domain = getattr(context, 'i18n_domain', '')
if not domain:
diff --git a/src/zope/configuration/tests/test_docs.py b/src/zope/configuration/tests/test_docs.py
index 915d2f0..e51a095 100644
--- a/src/zope/configuration/tests/test_docs.py
+++ b/src/zope/configuration/tests/test_docs.py
@@ -20,6 +20,7 @@ from __future__ import division
from __future__ import print_function
import re
+import sys
import os.path
import unittest
import doctest
@@ -41,6 +42,11 @@ checker = renormalizing.RENormalizing([
(re.compile('b(".*?")'), r"\1"),
])
+optionflags = (
+ doctest.NORMALIZE_WHITESPACE
+ | doctest.ELLIPSIS
+ | doctest.IGNORE_EXCEPTION_DETAIL
+)
def test_suite():
here = os.path.dirname(os.path.abspath(__file__))
@@ -64,15 +70,22 @@ def test_suite():
'xmlconfig.rst',
)
+ # Plain doctest suites
+ api_to_test = (
+ 'config',
+ 'docutils',
+ 'fields',
+ 'interfaces',
+ 'name',
+ 'xmlconfig',
+ 'zopeconfigure',
+ )
+
paths = [os.path.join(docs, f) for f in doc_files_to_test]
paths += [os.path.join(api_docs, f) for f in api_files_to_test]
m = manuel.ignore.Manuel()
- m += manuel.doctest.Manuel(checker=checker, optionflags=(
- doctest.NORMALIZE_WHITESPACE
- | doctest.ELLIPSIS
- | doctest.IGNORE_EXCEPTION_DETAIL
- ))
+ m += manuel.doctest.Manuel(checker=checker, optionflags=optionflags)
m += manuel.codeblock.Manuel()
m += manuel.capture.Manuel()
@@ -84,4 +97,15 @@ def test_suite():
)
)
+ for mod_name in api_to_test:
+ mod_name = 'zope.configuration.' + mod_name
+ __import__(mod_name)
+ suite.addTest(
+ doctest.DocTestSuite(
+ sys.modules[mod_name],
+ checker=checker,
+ optionflags=optionflags
+ )
+ )
+
return suite