[Checkins] SVN: manuel/trunk/ merge in svn+ssh://svn.zope.org/repos/main/manuel/branches/jim-multiple-doctest

Benji York benji+zope.org at benjiyork.com
Tue Jan 25 21:46:01 EST 2011


Log message for revision 119938:
  merge in svn+ssh://svn.zope.org/repos/main/manuel/branches/jim-multiple-doctest
  (plus a small whitespace tweak)
  

Changed:
  U   manuel/trunk/CHANGES.txt
  U   manuel/trunk/src/manuel/README.txt
  U   manuel/trunk/src/manuel/doctest.py
  U   manuel/trunk/src/manuel/tests.py

-=-
Modified: manuel/trunk/CHANGES.txt
===================================================================
--- manuel/trunk/CHANGES.txt	2011-01-26 02:34:15 UTC (rev 119937)
+++ manuel/trunk/CHANGES.txt	2011-01-26 02:46:00 UTC (rev 119938)
@@ -1,6 +1,14 @@
 CHANGES
 =======
 
+1.4.1 (2011-01-19)
+------------------
+
+- Fixed a bug that caused extra example evaluation if multiple doctest
+  manuels were used at once (e.g. to execute Python and shell code in
+  the same document).
+
+
 1.4.0 (2011-01-11)
 ------------------
 
@@ -9,6 +17,7 @@
   adding support for other languages or other (but similar) example
   syntaxes.
 
+
 1.3.0 (2010-09-02)
 ------------------
 

Modified: manuel/trunk/src/manuel/README.txt
===================================================================
--- manuel/trunk/src/manuel/README.txt	2011-01-26 02:34:15 UTC (rev 119937)
+++ manuel/trunk/src/manuel/README.txt	2011-01-26 02:46:00 UTC (rev 119938)
@@ -296,6 +296,31 @@
     Got:
         2
 
+Multiple doctest parsers
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+You may use several doctest parsers in the same session, for example,
+to support shell commands and Python code in the same document.
+
+    >>> m = (manuel.doctest.Manuel(parser=DocTestPyParser()) +
+    ...      manuel.doctest.Manuel())
+
+    >>> document = manuel.Document("""
+    ...
+    ...     py> i = 0
+    ...     py> i += 1
+    ...     py> i
+    ...     1
+    ...
+    ...     >>> j = 0
+    ...     >>> j += 1
+    ...     >>> j
+    ...     1
+    ...
+    ... """)
+    >>> document.process_with(m, globs={})
+    >>> print document.formatted(),
+
 Globals
 -------
 
@@ -581,6 +606,7 @@
 Now when we have a failure, only the genuinely referenced variables will be
 included in the debugging information.
 
+    >>> document = manuel.Document(document.source)
     >>> document.process_with(m, globs={})
     >>> print document.formatted(),
     File "<memory>", line 10, in <memory>

Modified: manuel/trunk/src/manuel/doctest.py
===================================================================
--- manuel/trunk/src/manuel/doctest.py	2011-01-26 02:34:15 UTC (rev 119937)
+++ manuel/trunk/src/manuel/doctest.py	2011-01-26 02:46:00 UTC (rev 119938)
@@ -9,7 +9,7 @@
     pass
 
 
-def parse(document, parser):
+def parse(m, document, parser):
     for region in list(document):
         if region.parsed:
             continue
@@ -19,6 +19,8 @@
             # If the chunk contains prose (as opposed to and example), skip it.
             if isinstance(chunk, basestring):
                 continue
+
+            chunk._manual = m
             chunk_line_count = (chunk.source.count('\n')
                 + chunk.want.count('\n'))
 
@@ -55,7 +57,8 @@
 def evaluate(m, region, document, globs):
     # If the parsed object is not a doctest Example then we don't need to
     # handle it.
-    if not isinstance(region.parsed, doctest.Example):
+
+    if getattr(region.parsed, '_manual', None) is not m:
         return
 
     result = DocTestResult()
@@ -102,5 +105,5 @@
         parser = parser or doctest.DocTestParser()
         manuel.Manuel.__init__(
             self,
-            [lambda document: parse(document, parser)],
+            [lambda document: parse(self, document, parser)],
             [evaluate_closure], [format])

Modified: manuel/trunk/src/manuel/tests.py
===================================================================
--- manuel/trunk/src/manuel/tests.py	2011-01-26 02:34:15 UTC (rev 119937)
+++ manuel/trunk/src/manuel/tests.py	2011-01-26 02:46:00 UTC (rev 119938)
@@ -1,3 +1,4 @@
+import doctest
 import manuel
 import manuel.capture
 import manuel.codeblock
@@ -18,6 +19,32 @@
     (re.compile(r"<unittest\.result\.TestResult"), '<unittest.TestResult'),
     ])
 
+
+def turtle_on_the_bottom_test():
+    """We use manuel to test itself.
+
+    This means that if we completely hose manuel, we might not
+    know. Use doctest to do a basic sanity check.
+
+    >>> document = manuel.Document('''This is my doctest.
+    ...
+    ...     >>> 2 + 2
+    ...     5
+    ... ''')
+    >>> document.process_with(manuel.doctest.Manuel(), globs={})
+    >>> print document.formatted()
+    File "<memory>", line 3, in <memory>
+    Failed example:
+        2 + 2
+    Expected:
+        5
+    Got:
+        4
+    <BLANKLINE>
+
+    """
+
+
 def test_suite():
     tests = ['../index.txt', 'table-example.txt', 'README.txt', 'bugs.txt',
         'capture.txt']
@@ -31,9 +58,15 @@
     m += manuel.testcase.SectionManuel()
     # The apparently redundant "**dict()" is to make this code compatible with
     # Python 2.5 -- it would generate a SyntaxError otherwise.
-    return manuel.testing.TestSuite(m, *tests, **dict(
+    suite = manuel.testing.TestSuite(m, *tests, **dict(
         globs={'path_to_test': os.path.join(here, 'bugs.txt')}))
 
 
+    return unittest.TestSuite((
+        suite,
+        doctest.DocTestSuite(),
+        ))
+
+
 if __name__ == '__main__':
     unittest.TextTestRunner().run(test_suite())



More information about the checkins mailing list