mirror of
				https://github.com/python/cpython.git
				synced 2025-10-25 18:54:53 +00:00 
			
		
		
		
	 052d0cd291
			
		
	
	
		052d0cd291
		
	
	
	
	
		
			
			all examples in a given text file. (analagous to "testmod") - Minor docstring fixes. - Added module_relative parameter to DocTestFile/DocTestSuite, which controls whether paths are module-relative & os-independent, or os-specific.
		
			
				
	
	
		
			2274 lines
		
	
	
	
		
			68 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			2274 lines
		
	
	
	
		
			68 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| """
 | |
| Test script for doctest.
 | |
| """
 | |
| 
 | |
| from test import test_support
 | |
| import doctest
 | |
| import warnings
 | |
| 
 | |
| ######################################################################
 | |
| ## Sample Objects (used by test cases)
 | |
| ######################################################################
 | |
| 
 | |
| def sample_func(v):
 | |
|     """
 | |
|     Blah blah
 | |
| 
 | |
|     >>> print sample_func(22)
 | |
|     44
 | |
| 
 | |
|     Yee ha!
 | |
|     """
 | |
|     return v+v
 | |
| 
 | |
| class SampleClass:
 | |
|     """
 | |
|     >>> print 1
 | |
|     1
 | |
|     """
 | |
|     def __init__(self, val):
 | |
|         """
 | |
|         >>> print SampleClass(12).get()
 | |
|         12
 | |
|         """
 | |
|         self.val = val
 | |
| 
 | |
|     def double(self):
 | |
|         """
 | |
|         >>> print SampleClass(12).double().get()
 | |
|         24
 | |
|         """
 | |
|         return SampleClass(self.val + self.val)
 | |
| 
 | |
|     def get(self):
 | |
|         """
 | |
|         >>> print SampleClass(-5).get()
 | |
|         -5
 | |
|         """
 | |
|         return self.val
 | |
| 
 | |
|     def a_staticmethod(v):
 | |
|         """
 | |
|         >>> print SampleClass.a_staticmethod(10)
 | |
|         11
 | |
|         """
 | |
|         return v+1
 | |
|     a_staticmethod = staticmethod(a_staticmethod)
 | |
| 
 | |
|     def a_classmethod(cls, v):
 | |
|         """
 | |
|         >>> print SampleClass.a_classmethod(10)
 | |
|         12
 | |
|         >>> print SampleClass(0).a_classmethod(10)
 | |
|         12
 | |
|         """
 | |
|         return v+2
 | |
|     a_classmethod = classmethod(a_classmethod)
 | |
| 
 | |
|     a_property = property(get, doc="""
 | |
|         >>> print SampleClass(22).a_property
 | |
|         22
 | |
|         """)
 | |
| 
 | |
|     class NestedClass:
 | |
|         """
 | |
|         >>> x = SampleClass.NestedClass(5)
 | |
|         >>> y = x.square()
 | |
|         >>> print y.get()
 | |
|         25
 | |
|         """
 | |
|         def __init__(self, val=0):
 | |
|             """
 | |
|             >>> print SampleClass.NestedClass().get()
 | |
|             0
 | |
|             """
 | |
|             self.val = val
 | |
|         def square(self):
 | |
|             return SampleClass.NestedClass(self.val*self.val)
 | |
|         def get(self):
 | |
|             return self.val
 | |
| 
 | |
| class SampleNewStyleClass(object):
 | |
|     r"""
 | |
|     >>> print '1\n2\n3'
 | |
|     1
 | |
|     2
 | |
|     3
 | |
|     """
 | |
|     def __init__(self, val):
 | |
|         """
 | |
|         >>> print SampleNewStyleClass(12).get()
 | |
|         12
 | |
|         """
 | |
|         self.val = val
 | |
| 
 | |
|     def double(self):
 | |
|         """
 | |
|         >>> print SampleNewStyleClass(12).double().get()
 | |
|         24
 | |
|         """
 | |
|         return SampleNewStyleClass(self.val + self.val)
 | |
| 
 | |
|     def get(self):
 | |
|         """
 | |
|         >>> print SampleNewStyleClass(-5).get()
 | |
|         -5
 | |
|         """
 | |
|         return self.val
 | |
| 
 | |
| ######################################################################
 | |
| ## Fake stdin (for testing interactive debugging)
 | |
| ######################################################################
 | |
| 
 | |
| class _FakeInput:
 | |
|     """
 | |
|     A fake input stream for pdb's interactive debugger.  Whenever a
 | |
|     line is read, print it (to simulate the user typing it), and then
 | |
|     return it.  The set of lines to return is specified in the
 | |
|     constructor; they should not have trailing newlines.
 | |
|     """
 | |
|     def __init__(self, lines):
 | |
|         self.lines = lines
 | |
| 
 | |
|     def readline(self):
 | |
|         line = self.lines.pop(0)
 | |
|         print line
 | |
|         return line+'\n'
 | |
| 
 | |
| ######################################################################
 | |
| ## Test Cases
 | |
| ######################################################################
 | |
| 
 | |
| def test_Example(): r"""
 | |
| Unit tests for the `Example` class.
 | |
| 
 | |
| Example is a simple container class that holds:
 | |
|   - `source`: A source string.
 | |
|   - `want`: An expected output string.
 | |
|   - `exc_msg`: An expected exception message string (or None if no
 | |
|     exception is expected).
 | |
|   - `lineno`: A line number (within the docstring).
 | |
|   - `indent`: The example's indentation in the input string.
 | |
|   - `options`: An option dictionary, mapping option flags to True or
 | |
|     False.
 | |
| 
 | |
| These attributes are set by the constructor.  `source` and `want` are
 | |
| required; the other attributes all have default values:
 | |
| 
 | |
|     >>> example = doctest.Example('print 1', '1\n')
 | |
|     >>> (example.source, example.want, example.exc_msg,
 | |
|     ...  example.lineno, example.indent, example.options)
 | |
|     ('print 1\n', '1\n', None, 0, 0, {})
 | |
| 
 | |
| The first three attributes (`source`, `want`, and `exc_msg`) may be
 | |
| specified positionally; the remaining arguments should be specified as
 | |
| keyword arguments:
 | |
| 
 | |
|     >>> exc_msg = 'IndexError: pop from an empty list'
 | |
|     >>> example = doctest.Example('[].pop()', '', exc_msg,
 | |
|     ...                           lineno=5, indent=4,
 | |
|     ...                           options={doctest.ELLIPSIS: True})
 | |
|     >>> (example.source, example.want, example.exc_msg,
 | |
|     ...  example.lineno, example.indent, example.options)
 | |
|     ('[].pop()\n', '', 'IndexError: pop from an empty list\n', 5, 4, {8: True})
 | |
| 
 | |
| The constructor normalizes the `source` string to end in a newline:
 | |
| 
 | |
|     Source spans a single line: no terminating newline.
 | |
|     >>> e = doctest.Example('print 1', '1\n')
 | |
|     >>> e.source, e.want
 | |
|     ('print 1\n', '1\n')
 | |
| 
 | |
|     >>> e = doctest.Example('print 1\n', '1\n')
 | |
|     >>> e.source, e.want
 | |
|     ('print 1\n', '1\n')
 | |
| 
 | |
|     Source spans multiple lines: require terminating newline.
 | |
|     >>> e = doctest.Example('print 1;\nprint 2\n', '1\n2\n')
 | |
|     >>> e.source, e.want
 | |
|     ('print 1;\nprint 2\n', '1\n2\n')
 | |
| 
 | |
|     >>> e = doctest.Example('print 1;\nprint 2', '1\n2\n')
 | |
|     >>> e.source, e.want
 | |
|     ('print 1;\nprint 2\n', '1\n2\n')
 | |
| 
 | |
|     Empty source string (which should never appear in real examples)
 | |
|     >>> e = doctest.Example('', '')
 | |
|     >>> e.source, e.want
 | |
|     ('\n', '')
 | |
| 
 | |
| The constructor normalizes the `want` string to end in a newline,
 | |
| unless it's the empty string:
 | |
| 
 | |
|     >>> e = doctest.Example('print 1', '1\n')
 | |
|     >>> e.source, e.want
 | |
|     ('print 1\n', '1\n')
 | |
| 
 | |
|     >>> e = doctest.Example('print 1', '1')
 | |
|     >>> e.source, e.want
 | |
|     ('print 1\n', '1\n')
 | |
| 
 | |
|     >>> e = doctest.Example('print', '')
 | |
|     >>> e.source, e.want
 | |
|     ('print\n', '')
 | |
| 
 | |
| The constructor normalizes the `exc_msg` string to end in a newline,
 | |
| unless it's `None`:
 | |
| 
 | |
|     Message spans one line
 | |
|     >>> exc_msg = 'IndexError: pop from an empty list'
 | |
|     >>> e = doctest.Example('[].pop()', '', exc_msg)
 | |
|     >>> e.exc_msg
 | |
|     'IndexError: pop from an empty list\n'
 | |
| 
 | |
|     >>> exc_msg = 'IndexError: pop from an empty list\n'
 | |
|     >>> e = doctest.Example('[].pop()', '', exc_msg)
 | |
|     >>> e.exc_msg
 | |
|     'IndexError: pop from an empty list\n'
 | |
| 
 | |
|     Message spans multiple lines
 | |
|     >>> exc_msg = 'ValueError: 1\n  2'
 | |
|     >>> e = doctest.Example('raise ValueError("1\n  2")', '', exc_msg)
 | |
|     >>> e.exc_msg
 | |
|     'ValueError: 1\n  2\n'
 | |
| 
 | |
|     >>> exc_msg = 'ValueError: 1\n  2\n'
 | |
|     >>> e = doctest.Example('raise ValueError("1\n  2")', '', exc_msg)
 | |
|     >>> e.exc_msg
 | |
|     'ValueError: 1\n  2\n'
 | |
| 
 | |
|     Empty (but non-None) exception message (which should never appear
 | |
|     in real examples)
 | |
|     >>> exc_msg = ''
 | |
|     >>> e = doctest.Example('raise X()', '', exc_msg)
 | |
|     >>> e.exc_msg
 | |
|     '\n'
 | |
| """
 | |
| 
 | |
| def test_DocTest(): r"""
 | |
| Unit tests for the `DocTest` class.
 | |
| 
 | |
| DocTest is a collection of examples, extracted from a docstring, along
 | |
| with information about where the docstring comes from (a name,
 | |
| filename, and line number).  The docstring is parsed by the `DocTest`
 | |
| constructor:
 | |
| 
 | |
|     >>> docstring = '''
 | |
|     ...     >>> print 12
 | |
|     ...     12
 | |
|     ...
 | |
|     ... Non-example text.
 | |
|     ...
 | |
|     ...     >>> print 'another\example'
 | |
|     ...     another
 | |
|     ...     example
 | |
|     ... '''
 | |
|     >>> globs = {} # globals to run the test in.
 | |
|     >>> parser = doctest.DocTestParser()
 | |
|     >>> test = parser.get_doctest(docstring, globs, 'some_test',
 | |
|     ...                           'some_file', 20)
 | |
|     >>> print test
 | |
|     <DocTest some_test from some_file:20 (2 examples)>
 | |
|     >>> len(test.examples)
 | |
|     2
 | |
|     >>> e1, e2 = test.examples
 | |
|     >>> (e1.source, e1.want, e1.lineno)
 | |
|     ('print 12\n', '12\n', 1)
 | |
|     >>> (e2.source, e2.want, e2.lineno)
 | |
|     ("print 'another\\example'\n", 'another\nexample\n', 6)
 | |
| 
 | |
| Source information (name, filename, and line number) is available as
 | |
| attributes on the doctest object:
 | |
| 
 | |
|     >>> (test.name, test.filename, test.lineno)
 | |
|     ('some_test', 'some_file', 20)
 | |
| 
 | |
| The line number of an example within its containing file is found by
 | |
| adding the line number of the example and the line number of its
 | |
| containing test:
 | |
| 
 | |
|     >>> test.lineno + e1.lineno
 | |
|     21
 | |
|     >>> test.lineno + e2.lineno
 | |
|     26
 | |
| 
 | |
| If the docstring contains inconsistant leading whitespace in the
 | |
| expected output of an example, then `DocTest` will raise a ValueError:
 | |
| 
 | |
|     >>> docstring = r'''
 | |
|     ...       >>> print 'bad\nindentation'
 | |
|     ...       bad
 | |
|     ...     indentation
 | |
|     ...     '''
 | |
|     >>> parser.get_doctest(docstring, globs, 'some_test', 'filename', 0)
 | |
|     Traceback (most recent call last):
 | |
|     ValueError: line 4 of the docstring for some_test has inconsistent leading whitespace: 'indentation'
 | |
| 
 | |
| If the docstring contains inconsistent leading whitespace on
 | |
| continuation lines, then `DocTest` will raise a ValueError:
 | |
| 
 | |
|     >>> docstring = r'''
 | |
|     ...       >>> print ('bad indentation',
 | |
|     ...     ...          2)
 | |
|     ...       ('bad', 'indentation')
 | |
|     ...     '''
 | |
|     >>> parser.get_doctest(docstring, globs, 'some_test', 'filename', 0)
 | |
|     Traceback (most recent call last):
 | |
|     ValueError: line 2 of the docstring for some_test has inconsistent leading whitespace: '...          2)'
 | |
| 
 | |
| If there's no blank space after a PS1 prompt ('>>>'), then `DocTest`
 | |
| will raise a ValueError:
 | |
| 
 | |
|     >>> docstring = '>>>print 1\n1'
 | |
|     >>> parser.get_doctest(docstring, globs, 'some_test', 'filename', 0)
 | |
|     Traceback (most recent call last):
 | |
|     ValueError: line 1 of the docstring for some_test lacks blank after >>>: '>>>print 1'
 | |
| 
 | |
| If there's no blank space after a PS2 prompt ('...'), then `DocTest`
 | |
| will raise a ValueError:
 | |
| 
 | |
|     >>> docstring = '>>> if 1:\n...print 1\n1'
 | |
|     >>> parser.get_doctest(docstring, globs, 'some_test', 'filename', 0)
 | |
|     Traceback (most recent call last):
 | |
|     ValueError: line 2 of the docstring for some_test lacks blank after ...: '...print 1'
 | |
| 
 | |
| """
 | |
| 
 | |
| def test_DocTestFinder(): r"""
 | |
| Unit tests for the `DocTestFinder` class.
 | |
| 
 | |
| DocTestFinder is used to extract DocTests from an object's docstring
 | |
| and the docstrings of its contained objects.  It can be used with
 | |
| modules, functions, classes, methods, staticmethods, classmethods, and
 | |
| properties.
 | |
| 
 | |
| Finding Tests in Functions
 | |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~
 | |
| For a function whose docstring contains examples, DocTestFinder.find()
 | |
| will return a single test (for that function's docstring):
 | |
| 
 | |
|     >>> finder = doctest.DocTestFinder()
 | |
| 
 | |
| We'll simulate a __file__ attr that ends in pyc:
 | |
| 
 | |
|     >>> import test.test_doctest
 | |
|     >>> old = test.test_doctest.__file__
 | |
|     >>> test.test_doctest.__file__ = 'test_doctest.pyc'
 | |
| 
 | |
|     >>> tests = finder.find(sample_func)
 | |
| 
 | |
|     >>> print tests  # doctest: +ELLIPSIS
 | |
|     [<DocTest sample_func from ...:13 (1 example)>]
 | |
| 
 | |
| The exact name depends on how test_doctest was invoked, so allow for
 | |
| leading path components.
 | |
| 
 | |
|     >>> tests[0].filename # doctest: +ELLIPSIS
 | |
|     '...test_doctest.py'
 | |
| 
 | |
|     >>> test.test_doctest.__file__ = old
 | |
| 
 | |
| 
 | |
|     >>> e = tests[0].examples[0]
 | |
|     >>> (e.source, e.want, e.lineno)
 | |
|     ('print sample_func(22)\n', '44\n', 3)
 | |
| 
 | |
| By default, tests are created for objects with no docstring:
 | |
| 
 | |
|     >>> def no_docstring(v):
 | |
|     ...     pass
 | |
|     >>> finder.find(no_docstring)
 | |
|     []
 | |
| 
 | |
| However, the optional argument `exclude_empty` to the DocTestFinder
 | |
| constructor can be used to exclude tests for objects with empty
 | |
| docstrings:
 | |
| 
 | |
|     >>> def no_docstring(v):
 | |
|     ...     pass
 | |
|     >>> excl_empty_finder = doctest.DocTestFinder(exclude_empty=True)
 | |
|     >>> excl_empty_finder.find(no_docstring)
 | |
|     []
 | |
| 
 | |
| If the function has a docstring with no examples, then a test with no
 | |
| examples is returned.  (This lets `DocTestRunner` collect statistics
 | |
| about which functions have no tests -- but is that useful?  And should
 | |
| an empty test also be created when there's no docstring?)
 | |
| 
 | |
|     >>> def no_examples(v):
 | |
|     ...     ''' no doctest examples '''
 | |
|     >>> finder.find(no_examples) # doctest: +ELLIPSIS
 | |
|     [<DocTest no_examples from ...:1 (no examples)>]
 | |
| 
 | |
| Finding Tests in Classes
 | |
| ~~~~~~~~~~~~~~~~~~~~~~~~
 | |
| For a class, DocTestFinder will create a test for the class's
 | |
| docstring, and will recursively explore its contents, including
 | |
| methods, classmethods, staticmethods, properties, and nested classes.
 | |
| 
 | |
|     >>> finder = doctest.DocTestFinder()
 | |
|     >>> tests = finder.find(SampleClass)
 | |
|     >>> tests.sort()
 | |
|     >>> for t in tests:
 | |
|     ...     print '%2s  %s' % (len(t.examples), t.name)
 | |
|      1  SampleClass
 | |
|      3  SampleClass.NestedClass
 | |
|      1  SampleClass.NestedClass.__init__
 | |
|      1  SampleClass.__init__
 | |
|      2  SampleClass.a_classmethod
 | |
|      1  SampleClass.a_property
 | |
|      1  SampleClass.a_staticmethod
 | |
|      1  SampleClass.double
 | |
|      1  SampleClass.get
 | |
| 
 | |
| New-style classes are also supported:
 | |
| 
 | |
|     >>> tests = finder.find(SampleNewStyleClass)
 | |
|     >>> tests.sort()
 | |
|     >>> for t in tests:
 | |
|     ...     print '%2s  %s' % (len(t.examples), t.name)
 | |
|      1  SampleNewStyleClass
 | |
|      1  SampleNewStyleClass.__init__
 | |
|      1  SampleNewStyleClass.double
 | |
|      1  SampleNewStyleClass.get
 | |
| 
 | |
| Finding Tests in Modules
 | |
| ~~~~~~~~~~~~~~~~~~~~~~~~
 | |
| For a module, DocTestFinder will create a test for the class's
 | |
| docstring, and will recursively explore its contents, including
 | |
| functions, classes, and the `__test__` dictionary, if it exists:
 | |
| 
 | |
|     >>> # A module
 | |
|     >>> import new
 | |
|     >>> m = new.module('some_module')
 | |
|     >>> def triple(val):
 | |
|     ...     '''
 | |
|     ...     >>> print tripple(11)
 | |
|     ...     33
 | |
|     ...     '''
 | |
|     ...     return val*3
 | |
|     >>> m.__dict__.update({
 | |
|     ...     'sample_func': sample_func,
 | |
|     ...     'SampleClass': SampleClass,
 | |
|     ...     '__doc__': '''
 | |
|     ...         Module docstring.
 | |
|     ...             >>> print 'module'
 | |
|     ...             module
 | |
|     ...         ''',
 | |
|     ...     '__test__': {
 | |
|     ...         'd': '>>> print 6\n6\n>>> print 7\n7\n',
 | |
|     ...         'c': triple}})
 | |
| 
 | |
|     >>> finder = doctest.DocTestFinder()
 | |
|     >>> # Use module=test.test_doctest, to prevent doctest from
 | |
|     >>> # ignoring the objects since they weren't defined in m.
 | |
|     >>> import test.test_doctest
 | |
|     >>> tests = finder.find(m, module=test.test_doctest)
 | |
|     >>> tests.sort()
 | |
|     >>> for t in tests:
 | |
|     ...     print '%2s  %s' % (len(t.examples), t.name)
 | |
|      1  some_module
 | |
|      1  some_module.SampleClass
 | |
|      3  some_module.SampleClass.NestedClass
 | |
|      1  some_module.SampleClass.NestedClass.__init__
 | |
|      1  some_module.SampleClass.__init__
 | |
|      2  some_module.SampleClass.a_classmethod
 | |
|      1  some_module.SampleClass.a_property
 | |
|      1  some_module.SampleClass.a_staticmethod
 | |
|      1  some_module.SampleClass.double
 | |
|      1  some_module.SampleClass.get
 | |
|      1  some_module.__test__.c
 | |
|      2  some_module.__test__.d
 | |
|      1  some_module.sample_func
 | |
| 
 | |
| Duplicate Removal
 | |
| ~~~~~~~~~~~~~~~~~
 | |
| If a single object is listed twice (under different names), then tests
 | |
| will only be generated for it once:
 | |
| 
 | |
|     >>> from test import doctest_aliases
 | |
|     >>> tests = excl_empty_finder.find(doctest_aliases)
 | |
|     >>> tests.sort()
 | |
|     >>> print len(tests)
 | |
|     2
 | |
|     >>> print tests[0].name
 | |
|     test.doctest_aliases.TwoNames
 | |
| 
 | |
|     TwoNames.f and TwoNames.g are bound to the same object.
 | |
|     We can't guess which will be found in doctest's traversal of
 | |
|     TwoNames.__dict__ first, so we have to allow for either.
 | |
| 
 | |
|     >>> tests[1].name.split('.')[-1] in ['f', 'g']
 | |
|     True
 | |
| 
 | |
| Filter Functions
 | |
| ~~~~~~~~~~~~~~~~
 | |
| A filter function can be used to restrict which objects get examined,
 | |
| but this is temporary, undocumented internal support for testmod's
 | |
| deprecated isprivate gimmick.
 | |
| 
 | |
|     >>> def namefilter(prefix, base):
 | |
|     ...     return base.startswith('a_')
 | |
|     >>> tests = doctest.DocTestFinder(_namefilter=namefilter).find(SampleClass)
 | |
|     >>> tests.sort()
 | |
|     >>> for t in tests:
 | |
|     ...     print '%2s  %s' % (len(t.examples), t.name)
 | |
|      1  SampleClass
 | |
|      3  SampleClass.NestedClass
 | |
|      1  SampleClass.NestedClass.__init__
 | |
|      1  SampleClass.__init__
 | |
|      1  SampleClass.double
 | |
|      1  SampleClass.get
 | |
| 
 | |
| By default, that excluded objects with no doctests.  exclude_empty=False
 | |
| tells it to include (empty) tests for objects with no doctests.  This feature
 | |
| is really to support backward compatibility in what doctest.master.summarize()
 | |
| displays.
 | |
| 
 | |
|     >>> tests = doctest.DocTestFinder(_namefilter=namefilter,
 | |
|     ...                                exclude_empty=False).find(SampleClass)
 | |
|     >>> tests.sort()
 | |
|     >>> for t in tests:
 | |
|     ...     print '%2s  %s' % (len(t.examples), t.name)
 | |
|      1  SampleClass
 | |
|      3  SampleClass.NestedClass
 | |
|      1  SampleClass.NestedClass.__init__
 | |
|      0  SampleClass.NestedClass.get
 | |
|      0  SampleClass.NestedClass.square
 | |
|      1  SampleClass.__init__
 | |
|      1  SampleClass.double
 | |
|      1  SampleClass.get
 | |
| 
 | |
| If a given object is filtered out, then none of the objects that it
 | |
| contains will be added either:
 | |
| 
 | |
|     >>> def namefilter(prefix, base):
 | |
|     ...     return base == 'NestedClass'
 | |
|     >>> tests = doctest.DocTestFinder(_namefilter=namefilter).find(SampleClass)
 | |
|     >>> tests.sort()
 | |
|     >>> for t in tests:
 | |
|     ...     print '%2s  %s' % (len(t.examples), t.name)
 | |
|      1  SampleClass
 | |
|      1  SampleClass.__init__
 | |
|      2  SampleClass.a_classmethod
 | |
|      1  SampleClass.a_property
 | |
|      1  SampleClass.a_staticmethod
 | |
|      1  SampleClass.double
 | |
|      1  SampleClass.get
 | |
| 
 | |
| The filter function apply to contained objects, and *not* to the
 | |
| object explicitly passed to DocTestFinder:
 | |
| 
 | |
|     >>> def namefilter(prefix, base):
 | |
|     ...     return base == 'SampleClass'
 | |
|     >>> tests = doctest.DocTestFinder(_namefilter=namefilter).find(SampleClass)
 | |
|     >>> len(tests)
 | |
|     9
 | |
| 
 | |
| Turning off Recursion
 | |
| ~~~~~~~~~~~~~~~~~~~~~
 | |
| DocTestFinder can be told not to look for tests in contained objects
 | |
| using the `recurse` flag:
 | |
| 
 | |
|     >>> tests = doctest.DocTestFinder(recurse=False).find(SampleClass)
 | |
|     >>> tests.sort()
 | |
|     >>> for t in tests:
 | |
|     ...     print '%2s  %s' % (len(t.examples), t.name)
 | |
|      1  SampleClass
 | |
| 
 | |
| Line numbers
 | |
| ~~~~~~~~~~~~
 | |
| DocTestFinder finds the line number of each example:
 | |
| 
 | |
|     >>> def f(x):
 | |
|     ...     '''
 | |
|     ...     >>> x = 12
 | |
|     ...
 | |
|     ...     some text
 | |
|     ...
 | |
|     ...     >>> # examples are not created for comments & bare prompts.
 | |
|     ...     >>>
 | |
|     ...     ...
 | |
|     ...
 | |
|     ...     >>> for x in range(10):
 | |
|     ...     ...     print x,
 | |
|     ...     0 1 2 3 4 5 6 7 8 9
 | |
|     ...     >>> x/2
 | |
|     ...     6
 | |
|     ...     '''
 | |
|     >>> test = doctest.DocTestFinder().find(f)[0]
 | |
|     >>> [e.lineno for e in test.examples]
 | |
|     [1, 9, 12]
 | |
| """
 | |
| 
 | |
| def test_DocTestParser(): r"""
 | |
| Unit tests for the `DocTestParser` class.
 | |
| 
 | |
| DocTestParser is used to parse docstrings containing doctest examples.
 | |
| 
 | |
| The `parse` method divides a docstring into examples and intervening
 | |
| text:
 | |
| 
 | |
|     >>> s = '''
 | |
|     ...     >>> x, y = 2, 3  # no output expected
 | |
|     ...     >>> if 1:
 | |
|     ...     ...     print x
 | |
|     ...     ...     print y
 | |
|     ...     2
 | |
|     ...     3
 | |
|     ...
 | |
|     ...     Some text.
 | |
|     ...     >>> x+y
 | |
|     ...     5
 | |
|     ...     '''
 | |
|     >>> parser = doctest.DocTestParser()
 | |
|     >>> for piece in parser.parse(s):
 | |
|     ...     if isinstance(piece, doctest.Example):
 | |
|     ...         print 'Example:', (piece.source, piece.want, piece.lineno)
 | |
|     ...     else:
 | |
|     ...         print '   Text:', `piece`
 | |
|        Text: '\n'
 | |
|     Example: ('x, y = 2, 3  # no output expected\n', '', 1)
 | |
|        Text: ''
 | |
|     Example: ('if 1:\n    print x\n    print y\n', '2\n3\n', 2)
 | |
|        Text: '\nSome text.\n'
 | |
|     Example: ('x+y\n', '5\n', 9)
 | |
|        Text: ''
 | |
| 
 | |
| The `get_examples` method returns just the examples:
 | |
| 
 | |
|     >>> for piece in parser.get_examples(s):
 | |
|     ...     print (piece.source, piece.want, piece.lineno)
 | |
|     ('x, y = 2, 3  # no output expected\n', '', 1)
 | |
|     ('if 1:\n    print x\n    print y\n', '2\n3\n', 2)
 | |
|     ('x+y\n', '5\n', 9)
 | |
| 
 | |
| The `get_doctest` method creates a Test from the examples, along with the
 | |
| given arguments:
 | |
| 
 | |
|     >>> test = parser.get_doctest(s, {}, 'name', 'filename', lineno=5)
 | |
|     >>> (test.name, test.filename, test.lineno)
 | |
|     ('name', 'filename', 5)
 | |
|     >>> for piece in test.examples:
 | |
|     ...     print (piece.source, piece.want, piece.lineno)
 | |
|     ('x, y = 2, 3  # no output expected\n', '', 1)
 | |
|     ('if 1:\n    print x\n    print y\n', '2\n3\n', 2)
 | |
|     ('x+y\n', '5\n', 9)
 | |
| """
 | |
| 
 | |
| class test_DocTestRunner:
 | |
|     def basics(): r"""
 | |
| Unit tests for the `DocTestRunner` class.
 | |
| 
 | |
| DocTestRunner is used to run DocTest test cases, and to accumulate
 | |
| statistics.  Here's a simple DocTest case we can use:
 | |
| 
 | |
|     >>> def f(x):
 | |
|     ...     '''
 | |
|     ...     >>> x = 12
 | |
|     ...     >>> print x
 | |
|     ...     12
 | |
|     ...     >>> x/2
 | |
|     ...     6
 | |
|     ...     '''
 | |
|     >>> test = doctest.DocTestFinder().find(f)[0]
 | |
| 
 | |
| The main DocTestRunner interface is the `run` method, which runs a
 | |
| given DocTest case in a given namespace (globs).  It returns a tuple
 | |
| `(f,t)`, where `f` is the number of failed tests and `t` is the number
 | |
| of tried tests.
 | |
| 
 | |
|     >>> doctest.DocTestRunner(verbose=False).run(test)
 | |
|     (0, 3)
 | |
| 
 | |
| If any example produces incorrect output, then the test runner reports
 | |
| the failure and proceeds to the next example:
 | |
| 
 | |
|     >>> def f(x):
 | |
|     ...     '''
 | |
|     ...     >>> x = 12
 | |
|     ...     >>> print x
 | |
|     ...     14
 | |
|     ...     >>> x/2
 | |
|     ...     6
 | |
|     ...     '''
 | |
|     >>> test = doctest.DocTestFinder().find(f)[0]
 | |
|     >>> doctest.DocTestRunner(verbose=True).run(test)
 | |
|     ... # doctest: +ELLIPSIS
 | |
|     Trying:
 | |
|         x = 12
 | |
|     Expecting nothing
 | |
|     ok
 | |
|     Trying:
 | |
|         print x
 | |
|     Expecting:
 | |
|         14
 | |
|     **********************************************************************
 | |
|     File ..., line 4, in f
 | |
|     Failed example:
 | |
|         print x
 | |
|     Expected:
 | |
|         14
 | |
|     Got:
 | |
|         12
 | |
|     Trying:
 | |
|         x/2
 | |
|     Expecting:
 | |
|         6
 | |
|     ok
 | |
|     (1, 3)
 | |
| """
 | |
|     def verbose_flag(): r"""
 | |
| The `verbose` flag makes the test runner generate more detailed
 | |
| output:
 | |
| 
 | |
|     >>> def f(x):
 | |
|     ...     '''
 | |
|     ...     >>> x = 12
 | |
|     ...     >>> print x
 | |
|     ...     12
 | |
|     ...     >>> x/2
 | |
|     ...     6
 | |
|     ...     '''
 | |
|     >>> test = doctest.DocTestFinder().find(f)[0]
 | |
| 
 | |
|     >>> doctest.DocTestRunner(verbose=True).run(test)
 | |
|     Trying:
 | |
|         x = 12
 | |
|     Expecting nothing
 | |
|     ok
 | |
|     Trying:
 | |
|         print x
 | |
|     Expecting:
 | |
|         12
 | |
|     ok
 | |
|     Trying:
 | |
|         x/2
 | |
|     Expecting:
 | |
|         6
 | |
|     ok
 | |
|     (0, 3)
 | |
| 
 | |
| If the `verbose` flag is unspecified, then the output will be verbose
 | |
| iff `-v` appears in sys.argv:
 | |
| 
 | |
|     >>> # Save the real sys.argv list.
 | |
|     >>> old_argv = sys.argv
 | |
| 
 | |
|     >>> # If -v does not appear in sys.argv, then output isn't verbose.
 | |
|     >>> sys.argv = ['test']
 | |
|     >>> doctest.DocTestRunner().run(test)
 | |
|     (0, 3)
 | |
| 
 | |
|     >>> # If -v does appear in sys.argv, then output is verbose.
 | |
|     >>> sys.argv = ['test', '-v']
 | |
|     >>> doctest.DocTestRunner().run(test)
 | |
|     Trying:
 | |
|         x = 12
 | |
|     Expecting nothing
 | |
|     ok
 | |
|     Trying:
 | |
|         print x
 | |
|     Expecting:
 | |
|         12
 | |
|     ok
 | |
|     Trying:
 | |
|         x/2
 | |
|     Expecting:
 | |
|         6
 | |
|     ok
 | |
|     (0, 3)
 | |
| 
 | |
|     >>> # Restore sys.argv
 | |
|     >>> sys.argv = old_argv
 | |
| 
 | |
| In the remaining examples, the test runner's verbosity will be
 | |
| explicitly set, to ensure that the test behavior is consistent.
 | |
|     """
 | |
|     def exceptions(): r"""
 | |
| Tests of `DocTestRunner`'s exception handling.
 | |
| 
 | |
| An expected exception is specified with a traceback message.  The
 | |
| lines between the first line and the type/value may be omitted or
 | |
| replaced with any other string:
 | |
| 
 | |
|     >>> def f(x):
 | |
|     ...     '''
 | |
|     ...     >>> x = 12
 | |
|     ...     >>> print x/0
 | |
|     ...     Traceback (most recent call last):
 | |
|     ...     ZeroDivisionError: integer division or modulo by zero
 | |
|     ...     '''
 | |
|     >>> test = doctest.DocTestFinder().find(f)[0]
 | |
|     >>> doctest.DocTestRunner(verbose=False).run(test)
 | |
|     (0, 2)
 | |
| 
 | |
| An example may not generate output before it raises an exception; if
 | |
| it does, then the traceback message will not be recognized as
 | |
| signaling an expected exception, so the example will be reported as an
 | |
| unexpected exception:
 | |
| 
 | |
|     >>> def f(x):
 | |
|     ...     '''
 | |
|     ...     >>> x = 12
 | |
|     ...     >>> print 'pre-exception output', x/0
 | |
|     ...     pre-exception output
 | |
|     ...     Traceback (most recent call last):
 | |
|     ...     ZeroDivisionError: integer division or modulo by zero
 | |
|     ...     '''
 | |
|     >>> test = doctest.DocTestFinder().find(f)[0]
 | |
|     >>> doctest.DocTestRunner(verbose=False).run(test)
 | |
|     ... # doctest: +ELLIPSIS
 | |
|     **********************************************************************
 | |
|     File ..., line 4, in f
 | |
|     Failed example:
 | |
|         print 'pre-exception output', x/0
 | |
|     Exception raised:
 | |
|         ...
 | |
|         ZeroDivisionError: integer division or modulo by zero
 | |
|     (1, 2)
 | |
| 
 | |
| Exception messages may contain newlines:
 | |
| 
 | |
|     >>> def f(x):
 | |
|     ...     r'''
 | |
|     ...     >>> raise ValueError, 'multi\nline\nmessage'
 | |
|     ...     Traceback (most recent call last):
 | |
|     ...     ValueError: multi
 | |
|     ...     line
 | |
|     ...     message
 | |
|     ...     '''
 | |
|     >>> test = doctest.DocTestFinder().find(f)[0]
 | |
|     >>> doctest.DocTestRunner(verbose=False).run(test)
 | |
|     (0, 1)
 | |
| 
 | |
| If an exception is expected, but an exception with the wrong type or
 | |
| message is raised, then it is reported as a failure:
 | |
| 
 | |
|     >>> def f(x):
 | |
|     ...     r'''
 | |
|     ...     >>> raise ValueError, 'message'
 | |
|     ...     Traceback (most recent call last):
 | |
|     ...     ValueError: wrong message
 | |
|     ...     '''
 | |
|     >>> test = doctest.DocTestFinder().find(f)[0]
 | |
|     >>> doctest.DocTestRunner(verbose=False).run(test)
 | |
|     ... # doctest: +ELLIPSIS
 | |
|     **********************************************************************
 | |
|     File ..., line 3, in f
 | |
|     Failed example:
 | |
|         raise ValueError, 'message'
 | |
|     Expected:
 | |
|         Traceback (most recent call last):
 | |
|         ValueError: wrong message
 | |
|     Got:
 | |
|         Traceback (most recent call last):
 | |
|         ...
 | |
|         ValueError: message
 | |
|     (1, 1)
 | |
| 
 | |
| However, IGNORE_EXCEPTION_DETAIL can be used to allow a mismatch in the
 | |
| detail:
 | |
| 
 | |
|     >>> def f(x):
 | |
|     ...     r'''
 | |
|     ...     >>> raise ValueError, 'message' #doctest: +IGNORE_EXCEPTION_DETAIL
 | |
|     ...     Traceback (most recent call last):
 | |
|     ...     ValueError: wrong message
 | |
|     ...     '''
 | |
|     >>> test = doctest.DocTestFinder().find(f)[0]
 | |
|     >>> doctest.DocTestRunner(verbose=False).run(test)
 | |
|     (0, 1)
 | |
| 
 | |
| But IGNORE_EXCEPTION_DETAIL does not allow a mismatch in the exception type:
 | |
| 
 | |
|     >>> def f(x):
 | |
|     ...     r'''
 | |
|     ...     >>> raise ValueError, 'message' #doctest: +IGNORE_EXCEPTION_DETAIL
 | |
|     ...     Traceback (most recent call last):
 | |
|     ...     TypeError: wrong type
 | |
|     ...     '''
 | |
|     >>> test = doctest.DocTestFinder().find(f)[0]
 | |
|     >>> doctest.DocTestRunner(verbose=False).run(test)
 | |
|     ... # doctest: +ELLIPSIS
 | |
|     **********************************************************************
 | |
|     File ..., line 3, in f
 | |
|     Failed example:
 | |
|         raise ValueError, 'message' #doctest: +IGNORE_EXCEPTION_DETAIL
 | |
|     Expected:
 | |
|         Traceback (most recent call last):
 | |
|         TypeError: wrong type
 | |
|     Got:
 | |
|         Traceback (most recent call last):
 | |
|         ...
 | |
|         ValueError: message
 | |
|     (1, 1)
 | |
| 
 | |
| If an exception is raised but not expected, then it is reported as an
 | |
| unexpected exception:
 | |
| 
 | |
|     >>> def f(x):
 | |
|     ...     r'''
 | |
|     ...     >>> 1/0
 | |
|     ...     0
 | |
|     ...     '''
 | |
|     >>> test = doctest.DocTestFinder().find(f)[0]
 | |
|     >>> doctest.DocTestRunner(verbose=False).run(test)
 | |
|     ... # doctest: +ELLIPSIS
 | |
|     **********************************************************************
 | |
|     File ..., line 3, in f
 | |
|     Failed example:
 | |
|         1/0
 | |
|     Exception raised:
 | |
|         Traceback (most recent call last):
 | |
|         ...
 | |
|         ZeroDivisionError: integer division or modulo by zero
 | |
|     (1, 1)
 | |
| """
 | |
|     def optionflags(): r"""
 | |
| Tests of `DocTestRunner`'s option flag handling.
 | |
| 
 | |
| Several option flags can be used to customize the behavior of the test
 | |
| runner.  These are defined as module constants in doctest, and passed
 | |
| to the DocTestRunner constructor (multiple constants should be or-ed
 | |
| together).
 | |
| 
 | |
| The DONT_ACCEPT_TRUE_FOR_1 flag disables matches between True/False
 | |
| and 1/0:
 | |
| 
 | |
|     >>> def f(x):
 | |
|     ...     '>>> True\n1\n'
 | |
| 
 | |
|     >>> # Without the flag:
 | |
|     >>> test = doctest.DocTestFinder().find(f)[0]
 | |
|     >>> doctest.DocTestRunner(verbose=False).run(test)
 | |
|     (0, 1)
 | |
| 
 | |
|     >>> # With the flag:
 | |
|     >>> test = doctest.DocTestFinder().find(f)[0]
 | |
|     >>> flags = doctest.DONT_ACCEPT_TRUE_FOR_1
 | |
|     >>> doctest.DocTestRunner(verbose=False, optionflags=flags).run(test)
 | |
|     ... # doctest: +ELLIPSIS
 | |
|     **********************************************************************
 | |
|     File ..., line 2, in f
 | |
|     Failed example:
 | |
|         True
 | |
|     Expected:
 | |
|         1
 | |
|     Got:
 | |
|         True
 | |
|     (1, 1)
 | |
| 
 | |
| The DONT_ACCEPT_BLANKLINE flag disables the match between blank lines
 | |
| and the '<BLANKLINE>' marker:
 | |
| 
 | |
|     >>> def f(x):
 | |
|     ...     '>>> print "a\\n\\nb"\na\n<BLANKLINE>\nb\n'
 | |
| 
 | |
|     >>> # Without the flag:
 | |
|     >>> test = doctest.DocTestFinder().find(f)[0]
 | |
|     >>> doctest.DocTestRunner(verbose=False).run(test)
 | |
|     (0, 1)
 | |
| 
 | |
|     >>> # With the flag:
 | |
|     >>> test = doctest.DocTestFinder().find(f)[0]
 | |
|     >>> flags = doctest.DONT_ACCEPT_BLANKLINE
 | |
|     >>> doctest.DocTestRunner(verbose=False, optionflags=flags).run(test)
 | |
|     ... # doctest: +ELLIPSIS
 | |
|     **********************************************************************
 | |
|     File ..., line 2, in f
 | |
|     Failed example:
 | |
|         print "a\n\nb"
 | |
|     Expected:
 | |
|         a
 | |
|         <BLANKLINE>
 | |
|         b
 | |
|     Got:
 | |
|         a
 | |
|     <BLANKLINE>
 | |
|         b
 | |
|     (1, 1)
 | |
| 
 | |
| The NORMALIZE_WHITESPACE flag causes all sequences of whitespace to be
 | |
| treated as equal:
 | |
| 
 | |
|     >>> def f(x):
 | |
|     ...     '>>> print 1, 2, 3\n  1   2\n 3'
 | |
| 
 | |
|     >>> # Without the flag:
 | |
|     >>> test = doctest.DocTestFinder().find(f)[0]
 | |
|     >>> doctest.DocTestRunner(verbose=False).run(test)
 | |
|     ... # doctest: +ELLIPSIS
 | |
|     **********************************************************************
 | |
|     File ..., line 2, in f
 | |
|     Failed example:
 | |
|         print 1, 2, 3
 | |
|     Expected:
 | |
|           1   2
 | |
|          3
 | |
|     Got:
 | |
|         1 2 3
 | |
|     (1, 1)
 | |
| 
 | |
|     >>> # With the flag:
 | |
|     >>> test = doctest.DocTestFinder().find(f)[0]
 | |
|     >>> flags = doctest.NORMALIZE_WHITESPACE
 | |
|     >>> doctest.DocTestRunner(verbose=False, optionflags=flags).run(test)
 | |
|     (0, 1)
 | |
| 
 | |
|     An example from the docs:
 | |
|     >>> print range(20) #doctest: +NORMALIZE_WHITESPACE
 | |
|     [0,   1,  2,  3,  4,  5,  6,  7,  8,  9,
 | |
|     10,  11, 12, 13, 14, 15, 16, 17, 18, 19]
 | |
| 
 | |
| The ELLIPSIS flag causes ellipsis marker ("...") in the expected
 | |
| output to match any substring in the actual output:
 | |
| 
 | |
|     >>> def f(x):
 | |
|     ...     '>>> print range(15)\n[0, 1, 2, ..., 14]\n'
 | |
| 
 | |
|     >>> # Without the flag:
 | |
|     >>> test = doctest.DocTestFinder().find(f)[0]
 | |
|     >>> doctest.DocTestRunner(verbose=False).run(test)
 | |
|     ... # doctest: +ELLIPSIS
 | |
|     **********************************************************************
 | |
|     File ..., line 2, in f
 | |
|     Failed example:
 | |
|         print range(15)
 | |
|     Expected:
 | |
|         [0, 1, 2, ..., 14]
 | |
|     Got:
 | |
|         [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
 | |
|     (1, 1)
 | |
| 
 | |
|     >>> # With the flag:
 | |
|     >>> test = doctest.DocTestFinder().find(f)[0]
 | |
|     >>> flags = doctest.ELLIPSIS
 | |
|     >>> doctest.DocTestRunner(verbose=False, optionflags=flags).run(test)
 | |
|     (0, 1)
 | |
| 
 | |
|     ... also matches nothing:
 | |
| 
 | |
|     >>> for i in range(100):
 | |
|     ...     print i**2, #doctest: +ELLIPSIS
 | |
|     0 1...4...9 16 ... 36 49 64 ... 9801
 | |
| 
 | |
|     ... can be surprising; e.g., this test passes:
 | |
| 
 | |
|     >>> for i in range(21): #doctest: +ELLIPSIS
 | |
|     ...     print i,
 | |
|     0 1 2 ...1...2...0
 | |
| 
 | |
|     Examples from the docs:
 | |
| 
 | |
|     >>> print range(20) # doctest:+ELLIPSIS
 | |
|     [0, 1, ..., 18, 19]
 | |
| 
 | |
|     >>> print range(20) # doctest: +ELLIPSIS
 | |
|     ...                 # doctest: +NORMALIZE_WHITESPACE
 | |
|     [0,    1, ...,   18,    19]
 | |
| 
 | |
| The REPORT_UDIFF flag causes failures that involve multi-line expected
 | |
| and actual outputs to be displayed using a unified diff:
 | |
| 
 | |
|     >>> def f(x):
 | |
|     ...     r'''
 | |
|     ...     >>> print '\n'.join('abcdefg')
 | |
|     ...     a
 | |
|     ...     B
 | |
|     ...     c
 | |
|     ...     d
 | |
|     ...     f
 | |
|     ...     g
 | |
|     ...     h
 | |
|     ...     '''
 | |
| 
 | |
|     >>> # Without the flag:
 | |
|     >>> test = doctest.DocTestFinder().find(f)[0]
 | |
|     >>> doctest.DocTestRunner(verbose=False).run(test)
 | |
|     ... # doctest: +ELLIPSIS
 | |
|     **********************************************************************
 | |
|     File ..., line 3, in f
 | |
|     Failed example:
 | |
|         print '\n'.join('abcdefg')
 | |
|     Expected:
 | |
|         a
 | |
|         B
 | |
|         c
 | |
|         d
 | |
|         f
 | |
|         g
 | |
|         h
 | |
|     Got:
 | |
|         a
 | |
|         b
 | |
|         c
 | |
|         d
 | |
|         e
 | |
|         f
 | |
|         g
 | |
|     (1, 1)
 | |
| 
 | |
|     >>> # With the flag:
 | |
|     >>> test = doctest.DocTestFinder().find(f)[0]
 | |
|     >>> flags = doctest.REPORT_UDIFF
 | |
|     >>> doctest.DocTestRunner(verbose=False, optionflags=flags).run(test)
 | |
|     ... # doctest: +ELLIPSIS
 | |
|     **********************************************************************
 | |
|     File ..., line 3, in f
 | |
|     Failed example:
 | |
|         print '\n'.join('abcdefg')
 | |
|     Differences (unified diff with -expected +actual):
 | |
|         @@ -1,7 +1,7 @@
 | |
|          a
 | |
|         -B
 | |
|         +b
 | |
|          c
 | |
|          d
 | |
|         +e
 | |
|          f
 | |
|          g
 | |
|         -h
 | |
|     (1, 1)
 | |
| 
 | |
| The REPORT_CDIFF flag causes failures that involve multi-line expected
 | |
| and actual outputs to be displayed using a context diff:
 | |
| 
 | |
|     >>> # Reuse f() from the REPORT_UDIFF example, above.
 | |
|     >>> test = doctest.DocTestFinder().find(f)[0]
 | |
|     >>> flags = doctest.REPORT_CDIFF
 | |
|     >>> doctest.DocTestRunner(verbose=False, optionflags=flags).run(test)
 | |
|     ... # doctest: +ELLIPSIS
 | |
|     **********************************************************************
 | |
|     File ..., line 3, in f
 | |
|     Failed example:
 | |
|         print '\n'.join('abcdefg')
 | |
|     Differences (context diff with expected followed by actual):
 | |
|         ***************
 | |
|         *** 1,7 ****
 | |
|           a
 | |
|         ! B
 | |
|           c
 | |
|           d
 | |
|           f
 | |
|           g
 | |
|         - h
 | |
|         --- 1,7 ----
 | |
|           a
 | |
|         ! b
 | |
|           c
 | |
|           d
 | |
|         + e
 | |
|           f
 | |
|           g
 | |
|     (1, 1)
 | |
| 
 | |
| 
 | |
| The REPORT_NDIFF flag causes failures to use the difflib.Differ algorithm
 | |
| used by the popular ndiff.py utility.  This does intraline difference
 | |
| marking, as well as interline differences.
 | |
| 
 | |
|     >>> def f(x):
 | |
|     ...     r'''
 | |
|     ...     >>> print "a b  c d e f g h i   j k l m"
 | |
|     ...     a b c d e f g h i j k 1 m
 | |
|     ...     '''
 | |
|     >>> test = doctest.DocTestFinder().find(f)[0]
 | |
|     >>> flags = doctest.REPORT_NDIFF
 | |
|     >>> doctest.DocTestRunner(verbose=False, optionflags=flags).run(test)
 | |
|     ... # doctest: +ELLIPSIS
 | |
|     **********************************************************************
 | |
|     File ..., line 3, in f
 | |
|     Failed example:
 | |
|         print "a b  c d e f g h i   j k l m"
 | |
|     Differences (ndiff with -expected +actual):
 | |
|         - a b c d e f g h i j k 1 m
 | |
|         ?                       ^
 | |
|         + a b  c d e f g h i   j k l m
 | |
|         ?     +              ++    ^
 | |
|     (1, 1)
 | |
| 
 | |
| The REPORT_ONLY_FIRST_FAILURE supresses result output after the first
 | |
| failing example:
 | |
| 
 | |
|     >>> def f(x):
 | |
|     ...     r'''
 | |
|     ...     >>> print 1 # first success
 | |
|     ...     1
 | |
|     ...     >>> print 2 # first failure
 | |
|     ...     200
 | |
|     ...     >>> print 3 # second failure
 | |
|     ...     300
 | |
|     ...     >>> print 4 # second success
 | |
|     ...     4
 | |
|     ...     >>> print 5 # third failure
 | |
|     ...     500
 | |
|     ...     '''
 | |
|     >>> test = doctest.DocTestFinder().find(f)[0]
 | |
|     >>> flags = doctest.REPORT_ONLY_FIRST_FAILURE
 | |
|     >>> doctest.DocTestRunner(verbose=False, optionflags=flags).run(test)
 | |
|     ... # doctest: +ELLIPSIS
 | |
|     **********************************************************************
 | |
|     File ..., line 5, in f
 | |
|     Failed example:
 | |
|         print 2 # first failure
 | |
|     Expected:
 | |
|         200
 | |
|     Got:
 | |
|         2
 | |
|     (3, 5)
 | |
| 
 | |
| However, output from `report_start` is not supressed:
 | |
| 
 | |
|     >>> doctest.DocTestRunner(verbose=True, optionflags=flags).run(test)
 | |
|     ... # doctest: +ELLIPSIS
 | |
|     Trying:
 | |
|         print 1 # first success
 | |
|     Expecting:
 | |
|         1
 | |
|     ok
 | |
|     Trying:
 | |
|         print 2 # first failure
 | |
|     Expecting:
 | |
|         200
 | |
|     **********************************************************************
 | |
|     File ..., line 5, in f
 | |
|     Failed example:
 | |
|         print 2 # first failure
 | |
|     Expected:
 | |
|         200
 | |
|     Got:
 | |
|         2
 | |
|     (3, 5)
 | |
| 
 | |
| For the purposes of REPORT_ONLY_FIRST_FAILURE, unexpected exceptions
 | |
| count as failures:
 | |
| 
 | |
|     >>> def f(x):
 | |
|     ...     r'''
 | |
|     ...     >>> print 1 # first success
 | |
|     ...     1
 | |
|     ...     >>> raise ValueError(2) # first failure
 | |
|     ...     200
 | |
|     ...     >>> print 3 # second failure
 | |
|     ...     300
 | |
|     ...     >>> print 4 # second success
 | |
|     ...     4
 | |
|     ...     >>> print 5 # third failure
 | |
|     ...     500
 | |
|     ...     '''
 | |
|     >>> test = doctest.DocTestFinder().find(f)[0]
 | |
|     >>> flags = doctest.REPORT_ONLY_FIRST_FAILURE
 | |
|     >>> doctest.DocTestRunner(verbose=False, optionflags=flags).run(test)
 | |
|     ... # doctest: +ELLIPSIS
 | |
|     **********************************************************************
 | |
|     File ..., line 5, in f
 | |
|     Failed example:
 | |
|         raise ValueError(2) # first failure
 | |
|     Exception raised:
 | |
|         ...
 | |
|         ValueError: 2
 | |
|     (3, 5)
 | |
| 
 | |
|     """
 | |
| 
 | |
|     def option_directives(): r"""
 | |
| Tests of `DocTestRunner`'s option directive mechanism.
 | |
| 
 | |
| Option directives can be used to turn option flags on or off for a
 | |
| single example.  To turn an option on for an example, follow that
 | |
| example with a comment of the form ``# doctest: +OPTION``:
 | |
| 
 | |
|     >>> def f(x): r'''
 | |
|     ...     >>> print range(10)       # should fail: no ellipsis
 | |
|     ...     [0, 1, ..., 9]
 | |
|     ...
 | |
|     ...     >>> print range(10)       # doctest: +ELLIPSIS
 | |
|     ...     [0, 1, ..., 9]
 | |
|     ...     '''
 | |
|     >>> test = doctest.DocTestFinder().find(f)[0]
 | |
|     >>> doctest.DocTestRunner(verbose=False).run(test)
 | |
|     ... # doctest: +ELLIPSIS
 | |
|     **********************************************************************
 | |
|     File ..., line 2, in f
 | |
|     Failed example:
 | |
|         print range(10)       # should fail: no ellipsis
 | |
|     Expected:
 | |
|         [0, 1, ..., 9]
 | |
|     Got:
 | |
|         [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
 | |
|     (1, 2)
 | |
| 
 | |
| To turn an option off for an example, follow that example with a
 | |
| comment of the form ``# doctest: -OPTION``:
 | |
| 
 | |
|     >>> def f(x): r'''
 | |
|     ...     >>> print range(10)
 | |
|     ...     [0, 1, ..., 9]
 | |
|     ...
 | |
|     ...     >>> # should fail: no ellipsis
 | |
|     ...     >>> print range(10)       # doctest: -ELLIPSIS
 | |
|     ...     [0, 1, ..., 9]
 | |
|     ...     '''
 | |
|     >>> test = doctest.DocTestFinder().find(f)[0]
 | |
|     >>> doctest.DocTestRunner(verbose=False,
 | |
|     ...                       optionflags=doctest.ELLIPSIS).run(test)
 | |
|     ... # doctest: +ELLIPSIS
 | |
|     **********************************************************************
 | |
|     File ..., line 6, in f
 | |
|     Failed example:
 | |
|         print range(10)       # doctest: -ELLIPSIS
 | |
|     Expected:
 | |
|         [0, 1, ..., 9]
 | |
|     Got:
 | |
|         [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
 | |
|     (1, 2)
 | |
| 
 | |
| Option directives affect only the example that they appear with; they
 | |
| do not change the options for surrounding examples:
 | |
| 
 | |
|     >>> def f(x): r'''
 | |
|     ...     >>> print range(10)       # Should fail: no ellipsis
 | |
|     ...     [0, 1, ..., 9]
 | |
|     ...
 | |
|     ...     >>> print range(10)       # doctest: +ELLIPSIS
 | |
|     ...     [0, 1, ..., 9]
 | |
|     ...
 | |
|     ...     >>> print range(10)       # Should fail: no ellipsis
 | |
|     ...     [0, 1, ..., 9]
 | |
|     ...     '''
 | |
|     >>> test = doctest.DocTestFinder().find(f)[0]
 | |
|     >>> doctest.DocTestRunner(verbose=False).run(test)
 | |
|     ... # doctest: +ELLIPSIS
 | |
|     **********************************************************************
 | |
|     File ..., line 2, in f
 | |
|     Failed example:
 | |
|         print range(10)       # Should fail: no ellipsis
 | |
|     Expected:
 | |
|         [0, 1, ..., 9]
 | |
|     Got:
 | |
|         [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
 | |
|     **********************************************************************
 | |
|     File ..., line 8, in f
 | |
|     Failed example:
 | |
|         print range(10)       # Should fail: no ellipsis
 | |
|     Expected:
 | |
|         [0, 1, ..., 9]
 | |
|     Got:
 | |
|         [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
 | |
|     (2, 3)
 | |
| 
 | |
| Multiple options may be modified by a single option directive.  They
 | |
| may be separated by whitespace, commas, or both:
 | |
| 
 | |
|     >>> def f(x): r'''
 | |
|     ...     >>> print range(10)       # Should fail
 | |
|     ...     [0, 1,  ...,   9]
 | |
|     ...     >>> print range(10)       # Should succeed
 | |
|     ...     ... # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
 | |
|     ...     [0, 1,  ...,   9]
 | |
|     ...     '''
 | |
|     >>> test = doctest.DocTestFinder().find(f)[0]
 | |
|     >>> doctest.DocTestRunner(verbose=False).run(test)
 | |
|     ... # doctest: +ELLIPSIS
 | |
|     **********************************************************************
 | |
|     File ..., line 2, in f
 | |
|     Failed example:
 | |
|         print range(10)       # Should fail
 | |
|     Expected:
 | |
|         [0, 1,  ...,   9]
 | |
|     Got:
 | |
|         [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
 | |
|     (1, 2)
 | |
| 
 | |
|     >>> def f(x): r'''
 | |
|     ...     >>> print range(10)       # Should fail
 | |
|     ...     [0, 1,  ...,   9]
 | |
|     ...     >>> print range(10)       # Should succeed
 | |
|     ...     ... # doctest: +ELLIPSIS,+NORMALIZE_WHITESPACE
 | |
|     ...     [0, 1,  ...,   9]
 | |
|     ...     '''
 | |
|     >>> test = doctest.DocTestFinder().find(f)[0]
 | |
|     >>> doctest.DocTestRunner(verbose=False).run(test)
 | |
|     ... # doctest: +ELLIPSIS
 | |
|     **********************************************************************
 | |
|     File ..., line 2, in f
 | |
|     Failed example:
 | |
|         print range(10)       # Should fail
 | |
|     Expected:
 | |
|         [0, 1,  ...,   9]
 | |
|     Got:
 | |
|         [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
 | |
|     (1, 2)
 | |
| 
 | |
|     >>> def f(x): r'''
 | |
|     ...     >>> print range(10)       # Should fail
 | |
|     ...     [0, 1,  ...,   9]
 | |
|     ...     >>> print range(10)       # Should succeed
 | |
|     ...     ... # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE
 | |
|     ...     [0, 1,  ...,   9]
 | |
|     ...     '''
 | |
|     >>> test = doctest.DocTestFinder().find(f)[0]
 | |
|     >>> doctest.DocTestRunner(verbose=False).run(test)
 | |
|     ... # doctest: +ELLIPSIS
 | |
|     **********************************************************************
 | |
|     File ..., line 2, in f
 | |
|     Failed example:
 | |
|         print range(10)       # Should fail
 | |
|     Expected:
 | |
|         [0, 1,  ...,   9]
 | |
|     Got:
 | |
|         [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
 | |
|     (1, 2)
 | |
| 
 | |
| The option directive may be put on the line following the source, as
 | |
| long as a continuation prompt is used:
 | |
| 
 | |
|     >>> def f(x): r'''
 | |
|     ...     >>> print range(10)
 | |
|     ...     ... # doctest: +ELLIPSIS
 | |
|     ...     [0, 1, ..., 9]
 | |
|     ...     '''
 | |
|     >>> test = doctest.DocTestFinder().find(f)[0]
 | |
|     >>> doctest.DocTestRunner(verbose=False).run(test)
 | |
|     (0, 1)
 | |
| 
 | |
| For examples with multi-line source, the option directive may appear
 | |
| at the end of any line:
 | |
| 
 | |
|     >>> def f(x): r'''
 | |
|     ...     >>> for x in range(10): # doctest: +ELLIPSIS
 | |
|     ...     ...     print x,
 | |
|     ...     0 1 2 ... 9
 | |
|     ...
 | |
|     ...     >>> for x in range(10):
 | |
|     ...     ...     print x,        # doctest: +ELLIPSIS
 | |
|     ...     0 1 2 ... 9
 | |
|     ...     '''
 | |
|     >>> test = doctest.DocTestFinder().find(f)[0]
 | |
|     >>> doctest.DocTestRunner(verbose=False).run(test)
 | |
|     (0, 2)
 | |
| 
 | |
| If more than one line of an example with multi-line source has an
 | |
| option directive, then they are combined:
 | |
| 
 | |
|     >>> def f(x): r'''
 | |
|     ...     Should fail (option directive not on the last line):
 | |
|     ...         >>> for x in range(10): # doctest: +ELLIPSIS
 | |
|     ...         ...     print x,        # doctest: +NORMALIZE_WHITESPACE
 | |
|     ...         0  1    2...9
 | |
|     ...     '''
 | |
|     >>> test = doctest.DocTestFinder().find(f)[0]
 | |
|     >>> doctest.DocTestRunner(verbose=False).run(test)
 | |
|     (0, 1)
 | |
| 
 | |
| It is an error to have a comment of the form ``# doctest:`` that is
 | |
| *not* followed by words of the form ``+OPTION`` or ``-OPTION``, where
 | |
| ``OPTION`` is an option that has been registered with
 | |
| `register_option`:
 | |
| 
 | |
|     >>> # Error: Option not registered
 | |
|     >>> s = '>>> print 12   #doctest: +BADOPTION'
 | |
|     >>> test = doctest.DocTestParser().get_doctest(s, {}, 's', 's.py', 0)
 | |
|     Traceback (most recent call last):
 | |
|     ValueError: line 1 of the doctest for s has an invalid option: '+BADOPTION'
 | |
| 
 | |
|     >>> # Error: No + or - prefix
 | |
|     >>> s = '>>> print 12   #doctest: ELLIPSIS'
 | |
|     >>> test = doctest.DocTestParser().get_doctest(s, {}, 's', 's.py', 0)
 | |
|     Traceback (most recent call last):
 | |
|     ValueError: line 1 of the doctest for s has an invalid option: 'ELLIPSIS'
 | |
| 
 | |
| It is an error to use an option directive on a line that contains no
 | |
| source:
 | |
| 
 | |
|     >>> s = '>>> # doctest: +ELLIPSIS'
 | |
|     >>> test = doctest.DocTestParser().get_doctest(s, {}, 's', 's.py', 0)
 | |
|     Traceback (most recent call last):
 | |
|     ValueError: line 0 of the doctest for s has an option directive on a line with no example: '# doctest: +ELLIPSIS'
 | |
| """
 | |
| 
 | |
| def test_testsource(): r"""
 | |
| Unit tests for `testsource()`.
 | |
| 
 | |
| The testsource() function takes a module and a name, finds the (first)
 | |
| test with that name in that module, and converts it to a script. The
 | |
| example code is converted to regular Python code.  The surrounding
 | |
| words and expected output are converted to comments:
 | |
| 
 | |
|     >>> import test.test_doctest
 | |
|     >>> name = 'test.test_doctest.sample_func'
 | |
|     >>> print doctest.testsource(test.test_doctest, name)
 | |
|     # Blah blah
 | |
|     #
 | |
|     print sample_func(22)
 | |
|     # Expected:
 | |
|     ## 44
 | |
|     #
 | |
|     # Yee ha!
 | |
| 
 | |
|     >>> name = 'test.test_doctest.SampleNewStyleClass'
 | |
|     >>> print doctest.testsource(test.test_doctest, name)
 | |
|     print '1\n2\n3'
 | |
|     # Expected:
 | |
|     ## 1
 | |
|     ## 2
 | |
|     ## 3
 | |
| 
 | |
|     >>> name = 'test.test_doctest.SampleClass.a_classmethod'
 | |
|     >>> print doctest.testsource(test.test_doctest, name)
 | |
|     print SampleClass.a_classmethod(10)
 | |
|     # Expected:
 | |
|     ## 12
 | |
|     print SampleClass(0).a_classmethod(10)
 | |
|     # Expected:
 | |
|     ## 12
 | |
| """
 | |
| 
 | |
| def test_debug(): r"""
 | |
| 
 | |
| Create a docstring that we want to debug:
 | |
| 
 | |
|     >>> s = '''
 | |
|     ...     >>> x = 12
 | |
|     ...     >>> print x
 | |
|     ...     12
 | |
|     ...     '''
 | |
| 
 | |
| Create some fake stdin input, to feed to the debugger:
 | |
| 
 | |
|     >>> import tempfile
 | |
|     >>> real_stdin = sys.stdin
 | |
|     >>> sys.stdin = _FakeInput(['next', 'print x', 'continue'])
 | |
| 
 | |
| Run the debugger on the docstring, and then restore sys.stdin.
 | |
| 
 | |
|     >>> try: doctest.debug_src(s)
 | |
|     ... finally: sys.stdin = real_stdin
 | |
|     > <string>(1)?()
 | |
|     (Pdb) next
 | |
|     12
 | |
|     --Return--
 | |
|     > <string>(1)?()->None
 | |
|     (Pdb) print x
 | |
|     12
 | |
|     (Pdb) continue
 | |
| 
 | |
| """
 | |
| 
 | |
| def test_pdb_set_trace():
 | |
|     """Using pdb.set_trace from a doctest
 | |
| 
 | |
|     You can use pdb.set_trace from a doctest.  To do so, you must
 | |
|     retrieve the set_trace function from the pdb module at the time
 | |
|     you use it.  The doctest module changes sys.stdout so that it can
 | |
|     capture program output.  It also temporarily replaces pdb.set_trace
 | |
|     with a version that restores stdout.  This is necessary for you to
 | |
|     see debugger output.
 | |
| 
 | |
|       >>> doc = '''
 | |
|       ... >>> x = 42
 | |
|       ... >>> import pdb; pdb.set_trace()
 | |
|       ... '''
 | |
|       >>> parser = doctest.DocTestParser()
 | |
|       >>> test = parser.get_doctest(doc, {}, "foo", "foo.py", 0)
 | |
|       >>> runner = doctest.DocTestRunner(verbose=False)
 | |
| 
 | |
|     To demonstrate this, we'll create a fake standard input that
 | |
|     captures our debugger input:
 | |
| 
 | |
|       >>> import tempfile
 | |
|       >>> real_stdin = sys.stdin
 | |
|       >>> sys.stdin = _FakeInput([
 | |
|       ...    'print x',  # print data defined by the example
 | |
|       ...    'continue', # stop debugging
 | |
|       ...    ''])
 | |
| 
 | |
|       >>> try: runner.run(test)
 | |
|       ... finally: sys.stdin = real_stdin
 | |
|       --Return--
 | |
|       > <doctest foo[1]>(1)?()->None
 | |
|       -> import pdb; pdb.set_trace()
 | |
|       (Pdb) print x
 | |
|       42
 | |
|       (Pdb) continue
 | |
|       (0, 2)
 | |
| 
 | |
|       You can also put pdb.set_trace in a function called from a test:
 | |
| 
 | |
|       >>> def calls_set_trace():
 | |
|       ...    y=2
 | |
|       ...    import pdb; pdb.set_trace()
 | |
| 
 | |
|       >>> doc = '''
 | |
|       ... >>> x=1
 | |
|       ... >>> calls_set_trace()
 | |
|       ... '''
 | |
|       >>> test = parser.get_doctest(doc, globals(), "foo", "foo.py", 0)
 | |
|       >>> real_stdin = sys.stdin
 | |
|       >>> sys.stdin = _FakeInput([
 | |
|       ...    'print y',  # print data defined in the function
 | |
|       ...    'up',       # out of function
 | |
|       ...    'print x',  # print data defined by the example
 | |
|       ...    'continue', # stop debugging
 | |
|       ...    ''])
 | |
| 
 | |
|       >>> try: runner.run(test)
 | |
|       ... finally: sys.stdin = real_stdin
 | |
|       --Return--
 | |
|       > <doctest test.test_doctest.test_pdb_set_trace[8]>(3)calls_set_trace()->None
 | |
|       -> import pdb; pdb.set_trace()
 | |
|       (Pdb) print y
 | |
|       2
 | |
|       (Pdb) up
 | |
|       > <doctest foo[1]>(1)?()
 | |
|       -> calls_set_trace()
 | |
|       (Pdb) print x
 | |
|       1
 | |
|       (Pdb) continue
 | |
|       (0, 2)
 | |
| 
 | |
|     During interactive debugging, source code is shown, even for
 | |
|     doctest examples:
 | |
| 
 | |
|       >>> doc = '''
 | |
|       ... >>> def f(x):
 | |
|       ... ...     g(x*2)
 | |
|       ... >>> def g(x):
 | |
|       ... ...     print x+3
 | |
|       ... ...     import pdb; pdb.set_trace()
 | |
|       ... >>> f(3)
 | |
|       ... '''
 | |
|       >>> test = parser.get_doctest(doc, globals(), "foo", "foo.py", 0)
 | |
|       >>> real_stdin = sys.stdin
 | |
|       >>> sys.stdin = _FakeInput([
 | |
|       ...    'list',     # list source from example 2
 | |
|       ...    'next',     # return from g()
 | |
|       ...    'list',     # list source from example 1
 | |
|       ...    'next',     # return from f()
 | |
|       ...    'list',     # list source from example 3
 | |
|       ...    'continue', # stop debugging
 | |
|       ...    ''])
 | |
|       >>> try: runner.run(test)
 | |
|       ... finally: sys.stdin = real_stdin
 | |
|       ... # doctest: +NORMALIZE_WHITESPACE
 | |
|       --Return--
 | |
|       > <doctest foo[1]>(3)g()->None
 | |
|       -> import pdb; pdb.set_trace()
 | |
|       (Pdb) list
 | |
|         1     def g(x):
 | |
|         2         print x+3
 | |
|         3  ->     import pdb; pdb.set_trace()
 | |
|       [EOF]
 | |
|       (Pdb) next
 | |
|       --Return--
 | |
|       > <doctest foo[0]>(2)f()->None
 | |
|       -> g(x*2)
 | |
|       (Pdb) list
 | |
|         1     def f(x):
 | |
|         2  ->     g(x*2)
 | |
|       [EOF]
 | |
|       (Pdb) next
 | |
|       --Return--
 | |
|       > <doctest foo[2]>(1)?()->None
 | |
|       -> f(3)
 | |
|       (Pdb) list
 | |
|         1  -> f(3)
 | |
|       [EOF]
 | |
|       (Pdb) continue
 | |
|       **********************************************************************
 | |
|       File "foo.py", line 7, in foo
 | |
|       Failed example:
 | |
|           f(3)
 | |
|       Expected nothing
 | |
|       Got:
 | |
|           9
 | |
|       (1, 3)
 | |
|       """
 | |
| 
 | |
| def test_DocTestSuite():
 | |
|     """DocTestSuite creates a unittest test suite from a doctest.
 | |
| 
 | |
|        We create a Suite by providing a module.  A module can be provided
 | |
|        by passing a module object:
 | |
| 
 | |
|          >>> import unittest
 | |
|          >>> import test.sample_doctest
 | |
|          >>> suite = doctest.DocTestSuite(test.sample_doctest)
 | |
|          >>> suite.run(unittest.TestResult())
 | |
|          <unittest.TestResult run=9 errors=0 failures=4>
 | |
| 
 | |
|        We can also supply the module by name:
 | |
| 
 | |
|          >>> suite = doctest.DocTestSuite('test.sample_doctest')
 | |
|          >>> suite.run(unittest.TestResult())
 | |
|          <unittest.TestResult run=9 errors=0 failures=4>
 | |
| 
 | |
|        We can use the current module:
 | |
| 
 | |
|          >>> suite = test.sample_doctest.test_suite()
 | |
|          >>> suite.run(unittest.TestResult())
 | |
|          <unittest.TestResult run=9 errors=0 failures=4>
 | |
| 
 | |
|        We can supply global variables.  If we pass globs, they will be
 | |
|        used instead of the module globals.  Here we'll pass an empty
 | |
|        globals, triggering an extra error:
 | |
| 
 | |
|          >>> suite = doctest.DocTestSuite('test.sample_doctest', globs={})
 | |
|          >>> suite.run(unittest.TestResult())
 | |
|          <unittest.TestResult run=9 errors=0 failures=5>
 | |
| 
 | |
|        Alternatively, we can provide extra globals.  Here we'll make an
 | |
|        error go away by providing an extra global variable:
 | |
| 
 | |
|          >>> suite = doctest.DocTestSuite('test.sample_doctest',
 | |
|          ...                              extraglobs={'y': 1})
 | |
|          >>> suite.run(unittest.TestResult())
 | |
|          <unittest.TestResult run=9 errors=0 failures=3>
 | |
| 
 | |
|        You can pass option flags.  Here we'll cause an extra error
 | |
|        by disabling the blank-line feature:
 | |
| 
 | |
|          >>> suite = doctest.DocTestSuite('test.sample_doctest',
 | |
|          ...                      optionflags=doctest.DONT_ACCEPT_BLANKLINE)
 | |
|          >>> suite.run(unittest.TestResult())
 | |
|          <unittest.TestResult run=9 errors=0 failures=5>
 | |
| 
 | |
|        You can supply setUp and tearDown functions:
 | |
| 
 | |
|          >>> def setUp(t):
 | |
|          ...     import test.test_doctest
 | |
|          ...     test.test_doctest.sillySetup = True
 | |
| 
 | |
|          >>> def tearDown(t):
 | |
|          ...     import test.test_doctest
 | |
|          ...     del test.test_doctest.sillySetup
 | |
| 
 | |
|        Here, we installed a silly variable that the test expects:
 | |
| 
 | |
|          >>> suite = doctest.DocTestSuite('test.sample_doctest',
 | |
|          ...      setUp=setUp, tearDown=tearDown)
 | |
|          >>> suite.run(unittest.TestResult())
 | |
|          <unittest.TestResult run=9 errors=0 failures=3>
 | |
| 
 | |
|        But the tearDown restores sanity:
 | |
| 
 | |
|          >>> import test.test_doctest
 | |
|          >>> test.test_doctest.sillySetup
 | |
|          Traceback (most recent call last):
 | |
|          ...
 | |
|          AttributeError: 'module' object has no attribute 'sillySetup'
 | |
| 
 | |
|        The setUp and tearDown funtions are passed test objects. Here
 | |
|        we'll use the setUp function to supply the missing variable y:
 | |
| 
 | |
|          >>> def setUp(test):
 | |
|          ...     test.globs['y'] = 1
 | |
| 
 | |
|          >>> suite = doctest.DocTestSuite('test.sample_doctest', setUp=setUp)
 | |
|          >>> suite.run(unittest.TestResult())
 | |
|          <unittest.TestResult run=9 errors=0 failures=3>
 | |
| 
 | |
|        Here, we didn't need to use a tearDown function because we
 | |
|        modified the test globals, which are a copy of the
 | |
|        sample_doctest module dictionary.  The test globals are
 | |
|        automatically cleared for us after a test.
 | |
| 
 | |
|        Finally, you can provide an alternate test finder.  Here we'll
 | |
|        use a custom test_finder to to run just the test named bar.
 | |
|        However, the test in the module docstring, and the two tests
 | |
|        in the module __test__ dict, aren't filtered, so we actually
 | |
|        run three tests besides bar's.  The filtering mechanisms are
 | |
|        poorly conceived, and will go away someday.
 | |
| 
 | |
|          >>> finder = doctest.DocTestFinder(
 | |
|          ...    _namefilter=lambda prefix, base: base!='bar')
 | |
|          >>> suite = doctest.DocTestSuite('test.sample_doctest',
 | |
|          ...                              test_finder=finder)
 | |
|          >>> suite.run(unittest.TestResult())
 | |
|          <unittest.TestResult run=4 errors=0 failures=1>
 | |
|        """
 | |
| 
 | |
| def test_DocFileSuite():
 | |
|     """We can test tests found in text files using a DocFileSuite.
 | |
| 
 | |
|        We create a suite by providing the names of one or more text
 | |
|        files that include examples:
 | |
| 
 | |
|          >>> import unittest
 | |
|          >>> suite = doctest.DocFileSuite('test_doctest.txt',
 | |
|          ...                              'test_doctest2.txt')
 | |
|          >>> suite.run(unittest.TestResult())
 | |
|          <unittest.TestResult run=2 errors=0 failures=2>
 | |
| 
 | |
|        The test files are looked for in the directory containing the
 | |
|        calling module.  A package keyword argument can be provided to
 | |
|        specify a different relative location.
 | |
| 
 | |
|          >>> import unittest
 | |
|          >>> suite = doctest.DocFileSuite('test_doctest.txt',
 | |
|          ...                              'test_doctest2.txt',
 | |
|          ...                              package='test')
 | |
|          >>> suite.run(unittest.TestResult())
 | |
|          <unittest.TestResult run=2 errors=0 failures=2>
 | |
| 
 | |
|        '/' should be used as a path separator.  It will be converted
 | |
|        to a native separator at run time:
 | |
| 
 | |
|          >>> suite = doctest.DocFileSuite('../test/test_doctest.txt')
 | |
|          >>> suite.run(unittest.TestResult())
 | |
|          <unittest.TestResult run=1 errors=0 failures=1>
 | |
| 
 | |
|        If DocFileSuite is used from an interactive session, then files
 | |
|        are resolved relative to the directory of sys.argv[0]:
 | |
| 
 | |
|          >>> import new, os.path, test.test_doctest
 | |
|          >>> save_argv = sys.argv
 | |
|          >>> sys.argv = [test.test_doctest.__file__]
 | |
|          >>> suite = doctest.DocFileSuite('test_doctest.txt',
 | |
|          ...                              package=new.module('__main__'))
 | |
|          >>> sys.argv = save_argv
 | |
| 
 | |
|        By setting `module_relative=False`, os-specific paths may be
 | |
|        used (including absolute paths and paths relative to the
 | |
|        working directory):
 | |
| 
 | |
|          >>> # Get the absolute path of the test package.
 | |
|          >>> test_doctest_path = os.path.abspath(test.test_doctest.__file__)
 | |
|          >>> test_pkg_path = os.path.split(test_doctest_path)[0]
 | |
| 
 | |
|          >>> # Use it to find the absolute path of test_doctest.txt.
 | |
|          >>> test_file = os.path.join(test_pkg_path, 'test_doctest.txt')
 | |
| 
 | |
|          >>> suite = doctest.DocFileSuite(test_file, module_relative=False)
 | |
|          >>> suite.run(unittest.TestResult())
 | |
|          <unittest.TestResult run=1 errors=0 failures=1>
 | |
| 
 | |
|        It is an error to specify `package` when `module_relative=False`:
 | |
| 
 | |
|          >>> suite = doctest.DocFileSuite(test_file, module_relative=False,
 | |
|          ...                              package='test')
 | |
|          Traceback (most recent call last):
 | |
|          ValueError: Package may only be specified for module-relative paths.
 | |
| 
 | |
|        You can specify initial global variables:
 | |
| 
 | |
|          >>> suite = doctest.DocFileSuite('test_doctest.txt',
 | |
|          ...                              'test_doctest2.txt',
 | |
|          ...                              globs={'favorite_color': 'blue'})
 | |
|          >>> suite.run(unittest.TestResult())
 | |
|          <unittest.TestResult run=2 errors=0 failures=1>
 | |
| 
 | |
|        In this case, we supplied a missing favorite color. You can
 | |
|        provide doctest options:
 | |
| 
 | |
|          >>> suite = doctest.DocFileSuite('test_doctest.txt',
 | |
|          ...                              'test_doctest2.txt',
 | |
|          ...                         optionflags=doctest.DONT_ACCEPT_BLANKLINE,
 | |
|          ...                              globs={'favorite_color': 'blue'})
 | |
|          >>> suite.run(unittest.TestResult())
 | |
|          <unittest.TestResult run=2 errors=0 failures=2>
 | |
| 
 | |
|        And, you can provide setUp and tearDown functions:
 | |
| 
 | |
|        You can supply setUp and teatDoen functions:
 | |
| 
 | |
|          >>> def setUp(t):
 | |
|          ...     import test.test_doctest
 | |
|          ...     test.test_doctest.sillySetup = True
 | |
| 
 | |
|          >>> def tearDown(t):
 | |
|          ...     import test.test_doctest
 | |
|          ...     del test.test_doctest.sillySetup
 | |
| 
 | |
|        Here, we installed a silly variable that the test expects:
 | |
| 
 | |
|          >>> suite = doctest.DocFileSuite('test_doctest.txt',
 | |
|          ...                              'test_doctest2.txt',
 | |
|          ...                              setUp=setUp, tearDown=tearDown)
 | |
|          >>> suite.run(unittest.TestResult())
 | |
|          <unittest.TestResult run=2 errors=0 failures=1>
 | |
| 
 | |
|        But the tearDown restores sanity:
 | |
| 
 | |
|          >>> import test.test_doctest
 | |
|          >>> test.test_doctest.sillySetup
 | |
|          Traceback (most recent call last):
 | |
|          ...
 | |
|          AttributeError: 'module' object has no attribute 'sillySetup'
 | |
| 
 | |
|        The setUp and tearDown funtions are passed test objects.
 | |
|        Here, we'll use a setUp function to set the favorite color in
 | |
|        test_doctest.txt:
 | |
| 
 | |
|          >>> def setUp(test):
 | |
|          ...     test.globs['favorite_color'] = 'blue'
 | |
| 
 | |
|          >>> suite = doctest.DocFileSuite('test_doctest.txt', setUp=setUp)
 | |
|          >>> suite.run(unittest.TestResult())
 | |
|          <unittest.TestResult run=1 errors=0 failures=0>
 | |
| 
 | |
|        Here, we didn't need to use a tearDown function because we
 | |
|        modified the test globals.  The test globals are
 | |
|        automatically cleared for us after a test.
 | |
| 
 | |
|        """
 | |
| 
 | |
| def test_trailing_space_in_test():
 | |
|     """
 | |
|     Trailing spaces in expected output are significant:
 | |
| 
 | |
|       >>> x, y = 'foo', ''
 | |
|       >>> print x, y
 | |
|       foo \n
 | |
|     """
 | |
| 
 | |
| 
 | |
| def test_unittest_reportflags():
 | |
|     """Default unittest reporting flags can be set to control reporting
 | |
| 
 | |
|     Here, we'll set the REPORT_ONLY_FIRST_FAILURE option so we see
 | |
|     only the first failure of each test.  First, we'll look at the
 | |
|     output without the flag.  The file test_doctest.txt file has two
 | |
|     tests. They both fail if blank lines are disabled:
 | |
| 
 | |
|       >>> suite = doctest.DocFileSuite('test_doctest.txt',
 | |
|       ...                          optionflags=doctest.DONT_ACCEPT_BLANKLINE)
 | |
|       >>> import unittest
 | |
|       >>> result = suite.run(unittest.TestResult())
 | |
|       >>> print result.failures[0][1] # doctest: +ELLIPSIS
 | |
|       Traceback ...
 | |
|       Failed example:
 | |
|           favorite_color
 | |
|       ...
 | |
|       Failed example:
 | |
|           if 1:
 | |
|       ...
 | |
| 
 | |
|     Note that we see both failures displayed.
 | |
| 
 | |
|       >>> old = doctest.set_unittest_reportflags(
 | |
|       ...    doctest.REPORT_ONLY_FIRST_FAILURE)
 | |
| 
 | |
|     Now, when we run the test:
 | |
| 
 | |
|       >>> result = suite.run(unittest.TestResult())
 | |
|       >>> print result.failures[0][1] # doctest: +ELLIPSIS
 | |
|       Traceback ...
 | |
|       Failed example:
 | |
|           favorite_color
 | |
|       Exception raised:
 | |
|           ...
 | |
|           NameError: name 'favorite_color' is not defined
 | |
|       <BLANKLINE>
 | |
|       <BLANKLINE>
 | |
| 
 | |
|     We get only the first failure.
 | |
| 
 | |
|     If we give any reporting options when we set up the tests,
 | |
|     however:
 | |
| 
 | |
|       >>> suite = doctest.DocFileSuite('test_doctest.txt',
 | |
|       ...     optionflags=doctest.DONT_ACCEPT_BLANKLINE | doctest.REPORT_NDIFF)
 | |
| 
 | |
|     Then the default eporting options are ignored:
 | |
| 
 | |
|       >>> result = suite.run(unittest.TestResult())
 | |
|       >>> print result.failures[0][1] # doctest: +ELLIPSIS
 | |
|       Traceback ...
 | |
|       Failed example:
 | |
|           favorite_color
 | |
|       ...
 | |
|       Failed example:
 | |
|           if 1:
 | |
|              print 'a'
 | |
|              print
 | |
|              print 'b'
 | |
|       Differences (ndiff with -expected +actual):
 | |
|             a
 | |
|           - <BLANKLINE>
 | |
|           +
 | |
|             b
 | |
|       <BLANKLINE>
 | |
|       <BLANKLINE>
 | |
| 
 | |
| 
 | |
|     Test runners can restore the formatting flags after they run:
 | |
| 
 | |
|       >>> ignored = doctest.set_unittest_reportflags(old)
 | |
| 
 | |
|     """
 | |
| 
 | |
| def test_testfile(): r"""
 | |
| Tests for the `testfile()` function.  This function runs all the
 | |
| doctest examples in a given file.  In its simple invokation, it is
 | |
| called with the name of a file, which is taken to be relative to the
 | |
| calling module.  The return value is (#failures, #tests).
 | |
| 
 | |
|     >>> doctest.testfile('test_doctest.txt') # doctest: +ELLIPSIS
 | |
|     **********************************************************************
 | |
|     File "...", line 6, in test_doctest.txt
 | |
|     Failed example:
 | |
|         favorite_color
 | |
|     Exception raised:
 | |
|         ...
 | |
|         NameError: name 'favorite_color' is not defined
 | |
|     **********************************************************************
 | |
|     1 items had failures:
 | |
|        1 of   2 in test_doctest.txt
 | |
|     ***Test Failed*** 1 failures.
 | |
|     (1, 2)
 | |
|     >>> doctest.master = None  # Reset master.
 | |
| 
 | |
| (Note: we'll be clearing doctest.master after each call to
 | |
| `doctest.testfile`, to supress warnings about multiple tests with the
 | |
| same name.)
 | |
| 
 | |
| Globals may be specified with the `globs` and `extraglobs` parameters:
 | |
| 
 | |
|     >>> globs = {'favorite_color': 'blue'}
 | |
|     >>> doctest.testfile('test_doctest.txt', globs=globs)
 | |
|     (0, 2)
 | |
|     >>> doctest.master = None  # Reset master.
 | |
| 
 | |
|     >>> extraglobs = {'favorite_color': 'red'}
 | |
|     >>> doctest.testfile('test_doctest.txt', globs=globs,
 | |
|     ...                  extraglobs=extraglobs) # doctest: +ELLIPSIS
 | |
|     **********************************************************************
 | |
|     File "...", line 6, in test_doctest.txt
 | |
|     Failed example:
 | |
|         favorite_color
 | |
|     Expected:
 | |
|         'blue'
 | |
|     Got:
 | |
|         'red'
 | |
|     **********************************************************************
 | |
|     1 items had failures:
 | |
|        1 of   2 in test_doctest.txt
 | |
|     ***Test Failed*** 1 failures.
 | |
|     (1, 2)
 | |
|     >>> doctest.master = None  # Reset master.
 | |
| 
 | |
| The file may be made relative to a given module or package, using the
 | |
| optional `module_relative` parameter:
 | |
| 
 | |
|     >>> doctest.testfile('test_doctest.txt', globs=globs,
 | |
|     ...                  module_relative='test')
 | |
|     (0, 2)
 | |
|     >>> doctest.master = None  # Reset master.
 | |
| 
 | |
| Verbosity can be increased with the optional `verbose` paremter:
 | |
| 
 | |
|     >>> doctest.testfile('test_doctest.txt', globs=globs, verbose=True)
 | |
|     Trying:
 | |
|         favorite_color
 | |
|     Expecting:
 | |
|         'blue'
 | |
|     ok
 | |
|     Trying:
 | |
|         if 1:
 | |
|            print 'a'
 | |
|            print
 | |
|            print 'b'
 | |
|     Expecting:
 | |
|         a
 | |
|         <BLANKLINE>
 | |
|         b
 | |
|     ok
 | |
|     1 items passed all tests:
 | |
|        2 tests in test_doctest.txt
 | |
|     2 tests in 1 items.
 | |
|     2 passed and 0 failed.
 | |
|     Test passed.
 | |
|     (0, 2)
 | |
|     >>> doctest.master = None  # Reset master.
 | |
| 
 | |
| The name of the test may be specified with the optional `name`
 | |
| parameter:
 | |
| 
 | |
|     >>> doctest.testfile('test_doctest.txt', name='newname')
 | |
|     ... # doctest: +ELLIPSIS
 | |
|     **********************************************************************
 | |
|     File "...", line 6, in newname
 | |
|     ...
 | |
|     (1, 2)
 | |
|     >>> doctest.master = None  # Reset master.
 | |
| 
 | |
| The summary report may be supressed with the optional `report`
 | |
| parameter:
 | |
| 
 | |
|     >>> doctest.testfile('test_doctest.txt', report=False)
 | |
|     ... # doctest: +ELLIPSIS
 | |
|     **********************************************************************
 | |
|     File "...", line 6, in test_doctest.txt
 | |
|     Failed example:
 | |
|         favorite_color
 | |
|     Exception raised:
 | |
|         ...
 | |
|         NameError: name 'favorite_color' is not defined
 | |
|     (1, 2)
 | |
|     >>> doctest.master = None  # Reset master.
 | |
| 
 | |
| The optional keyword argument `raise_on_error` can be used to raise an
 | |
| exception on the first error (which may be useful for postmortem
 | |
| debugging):
 | |
| 
 | |
|     >>> doctest.testfile('test_doctest.txt', raise_on_error=True)
 | |
|     ... # doctest: +ELLIPSIS
 | |
|     Traceback (most recent call last):
 | |
|     UnexpectedException: ...
 | |
|     >>> doctest.master = None  # Reset master.
 | |
| """
 | |
| 
 | |
| # old_test1, ... used to live in doctest.py, but cluttered it.  Note
 | |
| # that these use the deprecated doctest.Tester, so should go away (or
 | |
| # be rewritten) someday.
 | |
| 
 | |
| # Ignore all warnings about the use of class Tester in this module.
 | |
| # Note that the name of this module may differ depending on how it's
 | |
| # imported, so the use of __name__ is important.
 | |
| warnings.filterwarnings("ignore", "class Tester", DeprecationWarning,
 | |
|                         __name__, 0)
 | |
| 
 | |
| def old_test1(): r"""
 | |
| >>> from doctest import Tester
 | |
| >>> t = Tester(globs={'x': 42}, verbose=0)
 | |
| >>> t.runstring(r'''
 | |
| ...      >>> x = x * 2
 | |
| ...      >>> print x
 | |
| ...      42
 | |
| ... ''', 'XYZ')
 | |
| **********************************************************************
 | |
| Line 3, in XYZ
 | |
| Failed example:
 | |
|     print x
 | |
| Expected:
 | |
|     42
 | |
| Got:
 | |
|     84
 | |
| (1, 2)
 | |
| >>> t.runstring(">>> x = x * 2\n>>> print x\n84\n", 'example2')
 | |
| (0, 2)
 | |
| >>> t.summarize()
 | |
| **********************************************************************
 | |
| 1 items had failures:
 | |
|    1 of   2 in XYZ
 | |
| ***Test Failed*** 1 failures.
 | |
| (1, 4)
 | |
| >>> t.summarize(verbose=1)
 | |
| 1 items passed all tests:
 | |
|    2 tests in example2
 | |
| **********************************************************************
 | |
| 1 items had failures:
 | |
|    1 of   2 in XYZ
 | |
| 4 tests in 2 items.
 | |
| 3 passed and 1 failed.
 | |
| ***Test Failed*** 1 failures.
 | |
| (1, 4)
 | |
| """
 | |
| 
 | |
| def old_test2(): r"""
 | |
|         >>> from doctest import Tester
 | |
|         >>> t = Tester(globs={}, verbose=1)
 | |
|         >>> test = r'''
 | |
|         ...    # just an example
 | |
|         ...    >>> x = 1 + 2
 | |
|         ...    >>> x
 | |
|         ...    3
 | |
|         ... '''
 | |
|         >>> t.runstring(test, "Example")
 | |
|         Running string Example
 | |
|         Trying:
 | |
|             x = 1 + 2
 | |
|         Expecting nothing
 | |
|         ok
 | |
|         Trying:
 | |
|             x
 | |
|         Expecting:
 | |
|             3
 | |
|         ok
 | |
|         0 of 2 examples failed in string Example
 | |
|         (0, 2)
 | |
| """
 | |
| 
 | |
| def old_test3(): r"""
 | |
|         >>> from doctest import Tester
 | |
|         >>> t = Tester(globs={}, verbose=0)
 | |
|         >>> def _f():
 | |
|         ...     '''Trivial docstring example.
 | |
|         ...     >>> assert 2 == 2
 | |
|         ...     '''
 | |
|         ...     return 32
 | |
|         ...
 | |
|         >>> t.rundoc(_f)  # expect 0 failures in 1 example
 | |
|         (0, 1)
 | |
| """
 | |
| 
 | |
| def old_test4(): """
 | |
|         >>> import new
 | |
|         >>> m1 = new.module('_m1')
 | |
|         >>> m2 = new.module('_m2')
 | |
|         >>> test_data = \"""
 | |
|         ... def _f():
 | |
|         ...     '''>>> assert 1 == 1
 | |
|         ...     '''
 | |
|         ... def g():
 | |
|         ...    '''>>> assert 2 != 1
 | |
|         ...    '''
 | |
|         ... class H:
 | |
|         ...    '''>>> assert 2 > 1
 | |
|         ...    '''
 | |
|         ...    def bar(self):
 | |
|         ...        '''>>> assert 1 < 2
 | |
|         ...        '''
 | |
|         ... \"""
 | |
|         >>> exec test_data in m1.__dict__
 | |
|         >>> exec test_data in m2.__dict__
 | |
|         >>> m1.__dict__.update({"f2": m2._f, "g2": m2.g, "h2": m2.H})
 | |
| 
 | |
|         Tests that objects outside m1 are excluded:
 | |
| 
 | |
|         >>> from doctest import Tester
 | |
|         >>> t = Tester(globs={}, verbose=0)
 | |
|         >>> t.rundict(m1.__dict__, "rundict_test", m1)  # f2 and g2 and h2 skipped
 | |
|         (0, 4)
 | |
| 
 | |
|         Once more, not excluding stuff outside m1:
 | |
| 
 | |
|         >>> t = Tester(globs={}, verbose=0)
 | |
|         >>> t.rundict(m1.__dict__, "rundict_test_pvt")  # None are skipped.
 | |
|         (0, 8)
 | |
| 
 | |
|         The exclusion of objects from outside the designated module is
 | |
|         meant to be invoked automagically by testmod.
 | |
| 
 | |
|         >>> doctest.testmod(m1, verbose=False)
 | |
|         (0, 4)
 | |
| """
 | |
| 
 | |
| ######################################################################
 | |
| ## Main
 | |
| ######################################################################
 | |
| 
 | |
| def test_main():
 | |
|     # Check the doctest cases in doctest itself:
 | |
|     test_support.run_doctest(doctest, verbosity=True)
 | |
|     # Check the doctest cases defined here:
 | |
|     from test import test_doctest
 | |
|     test_support.run_doctest(test_doctest, verbosity=True)
 | |
| 
 | |
| import trace, sys, re, StringIO
 | |
| def test_coverage(coverdir):
 | |
|     tracer = trace.Trace(ignoredirs=[sys.prefix, sys.exec_prefix,],
 | |
|                          trace=0, count=1)
 | |
|     tracer.run('reload(doctest); test_main()')
 | |
|     r = tracer.results()
 | |
|     print 'Writing coverage results...'
 | |
|     r.write_results(show_missing=True, summary=True,
 | |
|                     coverdir=coverdir)
 | |
| 
 | |
| if __name__ == '__main__':
 | |
|     if '-c' in sys.argv:
 | |
|         test_coverage('/tmp/doctest.cover')
 | |
|     else:
 | |
|         test_main()
 |