[Checkins] SVN: manuel/trunk/ Added a ``parser`` keyword argument to manuel.doctest.Manuel to

Jim Fulton jim at zope.com
Tue Jan 11 10:32:15 EST 2011


Log message for revision 119503:
  Added a ``parser`` keyword argument to manuel.doctest.Manuel to
  allow a custom doctest parser to be passed in.  This allows easily
  adding support for other languages or other (but similar) example
  syntaxes.
  

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

-=-
Modified: manuel/trunk/CHANGES.txt
===================================================================
--- manuel/trunk/CHANGES.txt	2011-01-11 15:21:04 UTC (rev 119502)
+++ manuel/trunk/CHANGES.txt	2011-01-11 15:32:14 UTC (rev 119503)
@@ -1,6 +1,14 @@
 CHANGES
 =======
 
+1.4.0 (2011-01-11)
+------------------
+
+- Added a ``parser`` keyword argument to manuel.doctest.Manuel to
+  allow a custom doctest parser to be passed in.  This allows easily
+  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-11 15:21:04 UTC (rev 119502)
+++ manuel/trunk/src/manuel/README.txt	2011-01-11 15:32:14 UTC (rev 119503)
@@ -259,7 +259,43 @@
     Got:
         2
 
+Alternate doctest parsers
+~~~~~~~~~~~~~~~~~~~~~~~~~
 
+You can pass an alternate doctest parser to manuel.doctest.Manuel to
+customize how examples are parsed.  Here's an example that changes the
+example start string from ">>>" to "py>":
+
+    >>> import doctest
+    >>> class DocTestPyParser(doctest.DocTestParser):
+    ...    _EXAMPLE_RE = re.compile(r'''
+    ...        (?P<source>
+    ...             (?:^(?P<indent> [ ]*) py>    .*)    # PS1 line
+    ...            (?:\n           [ ]*  \.\.\. .*)*)  # PS2 lines
+    ...        \n?
+    ...        (?P<want> (?:(?![ ]*$)    # Not a blank line
+    ...                     (?![ ]*py>)  # Not a line starting with PS1
+    ...                     .*$\n?       # But any other line
+    ...                  )*)
+    ...        ''', re.MULTILINE | re.VERBOSE)
+
+    >>> m = manuel.doctest.Manuel(parser=DocTestPyParser())
+    >>> document = manuel.Document("""This is my
+    ... doctest.
+    ...
+    ...     py> 1 + 1
+    ...     42
+    ... """)
+    >>> document.process_with(m, globs={})
+    >>> print document.formatted(),
+    File "<memory>", line 4, in <memory>
+    Failed example:
+        1 + 1
+    Expected:
+        42
+    Got:
+        2
+
 Globals
 -------
 

Modified: manuel/trunk/src/manuel/doctest.py
===================================================================
--- manuel/trunk/src/manuel/doctest.py	2011-01-11 15:21:04 UTC (rev 119502)
+++ manuel/trunk/src/manuel/doctest.py	2011-01-11 15:32:14 UTC (rev 119503)
@@ -9,13 +9,13 @@
     pass
 
 
-def parse(document):
+def parse(document, parser):
     for region in list(document):
         if region.parsed:
             continue
         region_start = region.lineno
         region_end = region.lineno + region.source.count('\n')
-        for chunk in doctest.DocTestParser().parse(region.source):
+        for chunk in parser.parse(region.source):
             # If the chunk contains prose (as opposed to and example), skip it.
             if isinstance(chunk, basestring):
                 continue
@@ -92,11 +92,15 @@
 
 class Manuel(manuel.Manuel):
 
-    def __init__(self, optionflags=0, checker=None):
+    def __init__(self, optionflags=0, checker=None, parser=None):
         self.runner = doctest.DocTestRunner(optionflags=optionflags,
             checker=checker)
         self.debug_runner = doctest.DebugRunner(optionflags=optionflags)
         def evaluate_closure(region, document, globs):
             # capture "self"
             evaluate(self, region, document, globs)
-        manuel.Manuel.__init__(self, [parse], [evaluate_closure], [format])
+        parser = parser or doctest.DocTestParser()
+        manuel.Manuel.__init__(
+            self,
+            [lambda document: parse(document, parser)],
+            [evaluate_closure], [format])



More information about the checkins mailing list