[Checkins] SVN: Sandbox/shane/republish/zope.publisher/ Added tests and fixed stuff

Shane Hathaway shane at hathawaymix.org
Sat Feb 14 17:15:53 EST 2009


Log message for revision 96549:
  Added tests and fixed stuff
  

Changed:
  _U  Sandbox/shane/republish/zope.publisher/
  U   Sandbox/shane/republish/zope.publisher/setup.py
  _U  Sandbox/shane/republish/zope.publisher/src/
  A   Sandbox/shane/republish/zope.publisher/src/zope/publisher/README.txt
  A   Sandbox/shane/republish/zope.publisher/src/zope/publisher/browser.py
  U   Sandbox/shane/republish/zope.publisher/src/zope/publisher/interfaces/__init__.py
  U   Sandbox/shane/republish/zope.publisher/src/zope/publisher/interfaces/base.py
  U   Sandbox/shane/republish/zope.publisher/src/zope/publisher/interfaces/browser.py
  U   Sandbox/shane/republish/zope.publisher/src/zope/publisher/interfaces/exceptions.py
  U   Sandbox/shane/republish/zope.publisher/src/zope/publisher/interfaces/ftp.py
  U   Sandbox/shane/republish/zope.publisher/src/zope/publisher/interfaces/http.py
  U   Sandbox/shane/republish/zope.publisher/src/zope/publisher/interfaces/xmlrpc.py
  A   Sandbox/shane/republish/zope.publisher/src/zope/publisher/tests.py

-=-

Property changes on: Sandbox/shane/republish/zope.publisher
___________________________________________________________________
Added: svn:ignore
   + develop-eggs
parts
.installed.cfg
coverage
bin


Modified: Sandbox/shane/republish/zope.publisher/setup.py
===================================================================
--- Sandbox/shane/republish/zope.publisher/setup.py	2009-02-14 21:07:51 UTC (rev 96548)
+++ Sandbox/shane/republish/zope.publisher/setup.py	2009-02-14 22:15:52 UTC (rev 96549)
@@ -41,18 +41,9 @@
 
       namespace_packages=['zope',],
       install_requires=['setuptools',
+                        #'zope.deferredimport',
                         'zope.interface',
-
-                        'zope.component',
-                        'zope.event',
-                        'zope.i18n',
-                        'zope.interface',
                         'zope.location',
-                        'zope.proxy',
-                        'zope.security',
-                        'zope.deprecation',
-                        'zope.deferredimport',
-                        'zope.httpform',
                         ],
       extras_require=dict(
           test = ['zope.testing'],


Property changes on: Sandbox/shane/republish/zope.publisher/src
___________________________________________________________________
Added: svn:ignore
   + zope.publisher.egg-info


Added: Sandbox/shane/republish/zope.publisher/src/zope/publisher/README.txt
===================================================================
--- Sandbox/shane/republish/zope.publisher/src/zope/publisher/README.txt	                        (rev 0)
+++ Sandbox/shane/republish/zope.publisher/src/zope/publisher/README.txt	2009-02-14 22:15:52 UTC (rev 96549)
@@ -0,0 +1,67 @@
+
+BrowserView Tests
+-----------------
+
+    >>> from zope.publisher.browser import BrowserView
+    >>> view = BrowserView("context", "request")
+    >>> view.context
+    'context'
+    >>> view.request
+    'request'
+
+    >>> view.__parent__
+    'context'
+    >>> view.__parent__ = "parent"
+    >>> view.__parent__
+    'parent'
+
+BrowserPage Tests
+-----------------
+
+To create a page, which is an object that is published as a page,
+you need to provide an object that:
+
+- has a __call__ method and that
+
+- provides IBrowserPublisher, and
+
+- if ZPT is going to be used, then your object should also provide
+    request and context attributes.
+
+The BrowserPage base class provides a standard constructor and a
+simple implementation of IBrowserPage:
+
+    >>> from zope.publisher.browser import BrowserPage
+    >>> class MyPage(BrowserPage):
+    ...     pass
+
+    >>> request = object()
+    >>> context = object()
+    >>> page = MyPage(context, request)
+
+    >>> from zope.publisher.interfaces.browser import IBrowserPublisher
+    >>> IBrowserPublisher.providedBy(page)
+    True
+
+    >>> page.browserDefault(request) == (page, ())
+    True
+
+    >>> page.publishTraverse(request, 'bob') # doctest: +ELLIPSIS
+    Traceback (most recent call last):
+    ...
+    NotFound: Object: <MyPage object at ...>, name: 'bob'
+
+    >>> page.request is request
+    True
+
+    >>> page.context is context
+    True
+
+But it doesn't supply a __call__ method:
+
+    >>> page()
+    Traceback (most recent call last):
+    ...
+    NotImplementedError: Subclasses should override __call__ to provide a response body
+
+It is the subclass' responsibility to do that.

Added: Sandbox/shane/republish/zope.publisher/src/zope/publisher/browser.py
===================================================================
--- Sandbox/shane/republish/zope.publisher/src/zope/publisher/browser.py	                        (rev 0)
+++ Sandbox/shane/republish/zope.publisher/src/zope/publisher/browser.py	2009-02-14 22:15:52 UTC (rev 96549)
@@ -0,0 +1,62 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Browser-specific base classes
+
+$Id: browser.py 96546 2009-02-14 20:48:37Z shane $
+"""
+
+from zope.interface import implements
+from zope.location import Location
+
+from zope.publisher.interfaces.browser import IBrowserPage
+from zope.publisher.interfaces.browser import IBrowserView
+from zope.publisher.interfaces.exceptions import NotFound
+
+
+class BrowserView(Location):
+    """Browser View base class.
+
+    See the tests in README.txt.
+    """
+    implements(IBrowserView)
+
+    def __init__(self, context, request):
+        self.context = context
+        self.request = request
+
+    def _getParent(self):
+        return getattr(self, '_parent', self.context)
+
+    def _setParent(self, parent):
+        self._parent = parent
+
+    __parent__ = property(_getParent, _setParent)
+
+
+class BrowserPage(BrowserView):
+    """Browser page base class.
+
+    See the tests in README.txt.
+    """
+    implements(IBrowserPage)
+
+    def browserDefault(self, request):
+        return self, ()
+
+    def publishTraverse(self, request, name):
+        raise NotFound(self, name, request)
+
+    def __call__(self, *args, **kw):
+        raise NotImplementedError("Subclasses should override __call__ to "
+                                  "provide a response body")

Modified: Sandbox/shane/republish/zope.publisher/src/zope/publisher/interfaces/__init__.py
===================================================================
--- Sandbox/shane/republish/zope.publisher/src/zope/publisher/interfaces/__init__.py	2009-02-14 21:07:51 UTC (rev 96548)
+++ Sandbox/shane/republish/zope.publisher/src/zope/publisher/interfaces/__init__.py	2009-02-14 22:15:52 UTC (rev 96549)
@@ -1,14 +1,24 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Interfaces for publishing objects.
 
+$Id: browser.py 96546 2009-02-14 20:48:37Z shane $
+"""
 
-from zope.deferredimport import deprecatedFrom as _deprecatedFrom
-
 from zope.publisher.interfaces.base import *
 from zope.publisher.interfaces.exceptions import *
 from zope.publisher.interfaces.http import IRedirect
 from zope.publisher.interfaces.http import Redirect
 
 __all__ = tuple(name for name in globals() if not name.startswith('_'))
-
-_deprecatedFrom("Moved to zope.complextraversal.interfaces",
-    "zope.complextraversal.interfaces",
-    "IPublishTraverse")

Modified: Sandbox/shane/republish/zope.publisher/src/zope/publisher/interfaces/base.py
===================================================================
--- Sandbox/shane/republish/zope.publisher/src/zope/publisher/interfaces/base.py	2009-02-14 21:07:51 UTC (rev 96548)
+++ Sandbox/shane/republish/zope.publisher/src/zope/publisher/interfaces/base.py	2009-02-14 22:15:52 UTC (rev 96549)
@@ -1,12 +1,36 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Basic publisher interfaces.
 
+$Id: browser.py 96546 2009-02-14 20:48:37Z shane $
+"""
+
 """The base interfaces for request and response objects."""
 
 from zope.interface import Attribute
 from zope.interface import Interface
 from zope.interface.common.mapping import IExtendedReadMapping
 
-__all__ = ('IRequest', 'IResponse', 'IResult', 'IDebugFlags',
-    'IWSGIApplication')
+__all__ = (
+    'IRequest',
+    'IResponse',
+    'IResult',
+    'IHeld',
+    'IDebugFlags',
+    'IWSGIApplication',
+    'IPublishTraverse',
+    )
 
 
 class IRequest(IExtendedReadMapping):
@@ -52,7 +76,7 @@
         These hooks will be called before traversing an object for the
         first time.  If the same object is traversed more than
         once, the hook will still only be called the first time.
-        """
+        """)
 
     traversed = Attribute(
         """List of (name, obj) steps that have been traversed.
@@ -121,7 +145,18 @@
         """Deprecated: use response.unauthorized() instead.
         """
 
+    def hold(held):
+        """Hold a reference to an object until the request is closed.
 
+        If the object is an IHeld, its release method will be called
+        when the request is closed.
+        """
+
+    def close():
+        """Release resources held by the request.
+        """
+
+
 class IResponse(Interface):
     """Holds a response result."""
 
@@ -235,7 +270,17 @@
         See IResponse.setResult.
         """
 
+class IHeld(Interface):
+    """Object to be held and explicitly released by a request
+    """
 
+    def release():
+        """Release the held object
+
+        This is called by a request that holds the IHeld when the
+        request is closed.
+        """
+
 class IDebugFlags(Interface):
     """Features that support debugging."""
 
@@ -252,3 +297,18 @@
     def __call__(environ, start_response):
         """Call the application and return a body iterator."""
 
+
+class IPublishTraverse(Interface):
+
+    def publishTraverse(request, name):
+        """Traverse to a named item.
+
+        The 'request' argument is the publisher request object.  The
+        'name' argument is the name that is to be looked up; it must
+        be an ASCII string or Unicode object.
+
+        If a lookup is not possible, raise a NotFound error.
+
+        This method should return an object that provides ILocation,
+        having the specified name and `self` as parent.
+        """

Modified: Sandbox/shane/republish/zope.publisher/src/zope/publisher/interfaces/browser.py
===================================================================
--- Sandbox/shane/republish/zope.publisher/src/zope/publisher/interfaces/browser.py	2009-02-14 21:07:51 UTC (rev 96548)
+++ Sandbox/shane/republish/zope.publisher/src/zope/publisher/interfaces/browser.py	2009-02-14 22:15:52 UTC (rev 96549)
@@ -1,17 +1,82 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Browser-specific interfaces
 
+$Id: browser.py 96546 2009-02-14 20:48:37Z shane $
+"""
 
+from zope.interface import Attribute
 from zope.interface import Interface
 from zope.interface.interfaces import IInterface
-from zope.deferredimport import deprecatedFrom
+from zope.publisher.interfaces.base import IPublishTraverse
 from zope.publisher.interfaces.http import IHTTPRequest
 
+
 class IBrowserRequest(IHTTPRequest):
     """Browser-specific Request functionality.
 
-    Note that the browser is special in many ways, since it exposes
-    the Request object to the end-developer.
+    The improvement of ``IBrowserRequest`` over ``IHTTPRequest`` is
+    that it can hold HTML form data and file uploads in a
+    Python-friendly format.
     """
+    form = Attribute(
+        """Form data
 
+        This is a mapping from name to form value for the name.
+        """)
+
+    form_action = Attribute(
+        """The :action or :method specified by the form.""")
+
+
+class IBrowserPublisher(IPublishTraverse):
+    """Browser-specific traversal"""
+
+    def browserDefault(request):
+        """Provide the default object
+
+        The default object is expressed as a (possibly different)
+        object and/or additional traversal steps.
+
+        Returns an object and a sequence of names.  If the sequence of
+        names is not empty, then a traversal step is made for each name.
+        After the publisher gets to the end of the sequence, it will
+        call browserDefault on the last traversed object.
+
+        Normal usage is to return self for object and a default view name.
+
+        The publisher calls this method at the end of each traversal path. If
+        a non-empty sequence of names is returned, the publisher will traverse
+        those names and call browserDefault again at the end.
+
+        Note that if additional traversal steps are indicated (via a
+        nonempty sequence of names), then the publisher will try to adjust
+        the base href.
+        """
+
+class IBrowserPage(IBrowserPublisher):
+    """Browser page"""
+
+    def __call__(*args, **kw):
+        """Compute a response body"""
+
+class IBrowserView(Interface):
+    """Browser View"""
+
+class IDefaultBrowserLayer(IBrowserRequest):
+    """The default layer."""
+
 class IBrowserSkinType(IInterface):
     """A skin is a set of layers."""
 
@@ -26,10 +91,3 @@
     """Event that gets triggered when the skin of a request is changed."""
 
     request = Attribute("The request for which the skin was changed.")
-
-deprecatedFrom("moved to zope.complextraversal.interfaces",
-    "zope.complextraversal.interfaces",
-    "IBrowserPublisher",
-    "IBrowserPage",
-    "IBrowserView",
-    )

Modified: Sandbox/shane/republish/zope.publisher/src/zope/publisher/interfaces/exceptions.py
===================================================================
--- Sandbox/shane/republish/zope.publisher/src/zope/publisher/interfaces/exceptions.py	2009-02-14 21:07:51 UTC (rev 96548)
+++ Sandbox/shane/republish/zope.publisher/src/zope/publisher/interfaces/exceptions.py	2009-02-14 22:15:52 UTC (rev 96549)
@@ -1,4 +1,22 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Publishing exceptions.
 
+$Id: browser.py 96546 2009-02-14 20:48:37Z shane $
+"""
+
+from zope.interface import implements
 from zope.interface import Interface
 from zope.interface.common.interfaces import IException, ILookupError
 

Modified: Sandbox/shane/republish/zope.publisher/src/zope/publisher/interfaces/ftp.py
===================================================================
--- Sandbox/shane/republish/zope.publisher/src/zope/publisher/interfaces/ftp.py	2009-02-14 21:07:51 UTC (rev 96548)
+++ Sandbox/shane/republish/zope.publisher/src/zope/publisher/interfaces/ftp.py	2009-02-14 22:15:52 UTC (rev 96549)
@@ -1,11 +1,27 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""FTP-specific interfaces
 
-from zope.deferredimport import deprecatedFrom
+$Id: browser.py 96546 2009-02-14 20:48:37Z shane $
+"""
+
+from zope.publisher.interfaces.base import IPublishTraverse
 from zope.publisher.interfaces.base import IRequest
 
 class IFTPRequest(IRequest):
     """FTP Request
     """
 
-deprecatedFrom("moved to zope.complextraversal.interfaces",
-    "zope.complextraversal.interfaces",
-    "IFTPPublisher")
+class IFTPPublisher(IPublishTraverse):
+    """FTP-specific traversal"""

Modified: Sandbox/shane/republish/zope.publisher/src/zope/publisher/interfaces/http.py
===================================================================
--- Sandbox/shane/republish/zope.publisher/src/zope/publisher/interfaces/http.py	2009-02-14 21:07:51 UTC (rev 96548)
+++ Sandbox/shane/republish/zope.publisher/src/zope/publisher/interfaces/http.py	2009-02-14 22:15:52 UTC (rev 96549)
@@ -1,8 +1,27 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""HTTP-specific interfaces and exceptions
 
+$Id: browser.py 96546 2009-02-14 20:48:37Z shane $
+"""
+
 from zope.interface import Attribute
+from zope.interface import implements
 from zope.interface import Interface
-from zope.deferredimport import deprecatedFrom
+from zope.publisher.interfaces.base import IPublishTraverse
 from zope.publisher.interfaces.base import IRequest
+from zope.publisher.interfaces.base import IResponse
 from zope.publisher.interfaces.exceptions import IPublishingException
 from zope.publisher.interfaces.exceptions import PublishingException
 
@@ -50,15 +69,6 @@
 
     method = Attribute("Request method, normalized to upper case")
 
-    form = Attribute(
-        """Form data
-
-        This is a mapping from name to form value for the name.
-        """)
-
-    form_action = Attribute(
-        """The :action or :method specified by the form.""")
-
     def getCookies():
         """Return the cookie data
 
@@ -206,6 +216,6 @@
         """Causes a redirection without raising an error.
         """
 
-deprecatedFrom("moved to zope.complextraversal.interfaces",
-    "zope.complextraversal.interfaces",
-    "IHTTPPublisher")
+
+class IHTTPPublisher(IPublishTraverse):
+    """HTTP-Specific Traversal."""

Modified: Sandbox/shane/republish/zope.publisher/src/zope/publisher/interfaces/xmlrpc.py
===================================================================
--- Sandbox/shane/republish/zope.publisher/src/zope/publisher/interfaces/xmlrpc.py	2009-02-14 21:07:51 UTC (rev 96548)
+++ Sandbox/shane/republish/zope.publisher/src/zope/publisher/interfaces/xmlrpc.py	2009-02-14 22:15:52 UTC (rev 96549)
@@ -1,12 +1,27 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""XML-RPC interfaces
 
+$Id: browser.py 96546 2009-02-14 20:48:37Z shane $
+"""
 
-from zope.deferredimport import deprecatedFrom
+from zope.publisher.interfaces.base import IPublishTraverse
 from zope.publisher.interfaces.http import IHTTPRequest
 
 class IXMLRPCRequest(IHTTPRequest):
     """XML-RPC Request
     """
 
-deprecatedFrom("moved to zope.complextraversal.interfaces",
-    "zope.complextraversal.interfaces",
-    "IXMLRPCPublisher")
+class IXMLRPCPublisher(IPublishTraverse):
+    """XML-RPC-specific traversal"""

Added: Sandbox/shane/republish/zope.publisher/src/zope/publisher/tests.py
===================================================================
--- Sandbox/shane/republish/zope.publisher/src/zope/publisher/tests.py	                        (rev 0)
+++ Sandbox/shane/republish/zope.publisher/src/zope/publisher/tests.py	2009-02-14 22:15:52 UTC (rev 96549)
@@ -0,0 +1,28 @@
+##############################################################################
+#
+# Copyright (c) 2009 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Tests of this package"""
+
+import unittest
+
+from zope.testing import doctest
+
+def test_suite():
+    return unittest.TestSuite([
+        doctest.DocFileSuite(
+            'README.txt',
+            optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS),
+    ])
+
+if __name__ == '__main__':
+    unittest.main()



More information about the Checkins mailing list