Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(37711)

Delta Between Two Patch Sets: Lib/doctest.py

Issue 24746: doctest 'fancy diff' formats incorrectly strip trailing whitespace
Left Patch Set: Created 4 years, 1 month ago
Right Patch Set: Created 4 years, 1 month ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « no previous file | Lib/test/test_doctest.py » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 # Module doctest. 1 # Module doctest.
2 # Released to the public domain 16-Jan-2001, by Tim Peters (tim@python.org). 2 # Released to the public domain 16-Jan-2001, by Tim Peters (tim@python.org).
3 # Major enhancements and refactoring by: 3 # Major enhancements and refactoring by:
4 # Jim Fulton 4 # Jim Fulton
5 # Edward Loper 5 # Edward Loper
6 6
7 # Provided as-is; use at your own risk; no warranty; no promises; enjoy! 7 # Provided as-is; use at your own risk; no warranty; no promises; enjoy!
8 8
9 r"""Module doctest -- a framework for running examples in docstrings. 9 r"""Module doctest -- a framework for running examples in docstrings.
10 10
(...skipping 512 matching lines...) Expand 10 before | Expand all | Expand 10 after
523 self.filename = filename 523 self.filename = filename
524 self.lineno = lineno 524 self.lineno = lineno
525 525
526 def __repr__(self): 526 def __repr__(self):
527 if len(self.examples) == 0: 527 if len(self.examples) == 0:
528 examples = 'no examples' 528 examples = 'no examples'
529 elif len(self.examples) == 1: 529 elif len(self.examples) == 1:
530 examples = '1 example' 530 examples = '1 example'
531 else: 531 else:
532 examples = '%d examples' % len(self.examples) 532 examples = '%d examples' % len(self.examples)
533 return ('<DocTest %s from %s:%s (%s)>' % 533 return ('<%s %s from %s:%s (%s)>' %
534 (self.name, self.filename, self.lineno, examples)) 534 (self.__class__.__name__,
535 self.name, self.filename, self.lineno, examples))
535 536
536 def __eq__(self, other): 537 def __eq__(self, other):
537 if type(self) is not type(other): 538 if type(self) is not type(other):
538 return NotImplemented 539 return NotImplemented
539 540
540 return self.examples == other.examples and \ 541 return self.examples == other.examples and \
541 self.docstring == other.docstring and \ 542 self.docstring == other.docstring and \
542 self.globs == other.globs and \ 543 self.globs == other.globs and \
543 self.name == other.name and \ 544 self.name == other.name and \
544 self.filename == other.filename and \ 545 self.filename == other.filename and \
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after
971 # Find a test for this object, and add it to the list of tests. 972 # Find a test for this object, and add it to the list of tests.
972 test = self._get_test(obj, name, module, globs, source_lines) 973 test = self._get_test(obj, name, module, globs, source_lines)
973 if test is not None: 974 if test is not None:
974 tests.append(test) 975 tests.append(test)
975 976
976 # Look for tests in a module's contained objects. 977 # Look for tests in a module's contained objects.
977 if inspect.ismodule(obj) and self._recurse: 978 if inspect.ismodule(obj) and self._recurse:
978 for valname, val in obj.__dict__.items(): 979 for valname, val in obj.__dict__.items():
979 valname = '%s.%s' % (name, valname) 980 valname = '%s.%s' % (name, valname)
980 # Recurse to functions & classes. 981 # Recurse to functions & classes.
981 if ((inspect.isroutine(val) or inspect.isclass(val)) and 982 if ((inspect.isroutine(inspect.unwrap(val))
983 or inspect.isclass(val)) and
982 self._from_module(module, val)): 984 self._from_module(module, val)):
983 self._find(tests, val, valname, module, source_lines, 985 self._find(tests, val, valname, module, source_lines,
984 globs, seen) 986 globs, seen)
985 987
986 # Look for tests in a module's __test__ dictionary. 988 # Look for tests in a module's __test__ dictionary.
987 if inspect.ismodule(obj) and self._recurse: 989 if inspect.ismodule(obj) and self._recurse:
988 for valname, val in getattr(obj, '__test__', {}).items(): 990 for valname, val in getattr(obj, '__test__', {}).items():
989 if not isinstance(valname, str): 991 if not isinstance(valname, str):
990 raise ValueError("DocTestFinder.find: __test__ keys " 992 raise ValueError("DocTestFinder.find: __test__ keys "
991 "must be strings: %r" % 993 "must be strings: %r" %
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1042 1044
1043 # Don't bother if the docstring is empty. 1045 # Don't bother if the docstring is empty.
1044 if self._exclude_empty and not docstring: 1046 if self._exclude_empty and not docstring:
1045 return None 1047 return None
1046 1048
1047 # Return a DocTest for this object. 1049 # Return a DocTest for this object.
1048 if module is None: 1050 if module is None:
1049 filename = None 1051 filename = None
1050 else: 1052 else:
1051 filename = getattr(module, '__file__', module.__name__) 1053 filename = getattr(module, '__file__', module.__name__)
1052 if filename[-4:] in (".pyc", ".pyo"): 1054 if filename[-4:] == ".pyc":
1053 filename = filename[:-1] 1055 filename = filename[:-1]
1054 return self._parser.get_doctest(docstring, globs, name, 1056 return self._parser.get_doctest(docstring, globs, name,
1055 filename, lineno) 1057 filename, lineno)
1056 1058
1057 def _find_lineno(self, obj, source_lines): 1059 def _find_lineno(self, obj, source_lines):
1058 """ 1060 """
1059 Return a line number of the given object's docstring. Note: 1061 Return a line number of the given object's docstring. Note:
1060 this method assumes that the object has a docstring. 1062 this method assumes that the object has a docstring.
1061 """ 1063 """
1062 lineno = None 1064 lineno = None
(...skipping 609 matching lines...) Expand 10 before | Expand all | Expand 10 after
1672 elif optionflags & REPORT_CDIFF: 1674 elif optionflags & REPORT_CDIFF:
1673 diff = difflib.context_diff(want_lines, got_lines, n=2) 1675 diff = difflib.context_diff(want_lines, got_lines, n=2)
1674 diff = list(diff)[2:] # strip the diff header 1676 diff = list(diff)[2:] # strip the diff header
1675 kind = 'context diff with expected followed by actual' 1677 kind = 'context diff with expected followed by actual'
1676 elif optionflags & REPORT_NDIFF: 1678 elif optionflags & REPORT_NDIFF:
1677 engine = difflib.Differ(charjunk=difflib.IS_CHARACTER_JUNK) 1679 engine = difflib.Differ(charjunk=difflib.IS_CHARACTER_JUNK)
1678 diff = list(engine.compare(want_lines, got_lines)) 1680 diff = list(engine.compare(want_lines, got_lines))
1679 kind = 'ndiff with -expected +actual' 1681 kind = 'ndiff with -expected +actual'
1680 else: 1682 else:
1681 assert 0, 'Bad diff option' 1683 assert 0, 'Bad diff option'
1682 # Remove trailing whitespace on diff output.
1683 return 'Differences (%s):\n' % kind + _indent(''.join(diff)) 1684 return 'Differences (%s):\n' % kind + _indent(''.join(diff))
1684 1685
1685 # If we're not using diff, then simply list the expected 1686 # If we're not using diff, then simply list the expected
1686 # output followed by the actual output. 1687 # output followed by the actual output.
1687 if want and got: 1688 if want and got:
1688 return 'Expected:\n%sGot:\n%s' % (_indent(want), _indent(got)) 1689 return 'Expected:\n%sGot:\n%s' % (_indent(want), _indent(got))
1689 elif want: 1690 elif want:
1690 return 'Expected:\n%sGot nothing\n' % _indent(want) 1691 return 'Expected:\n%sGot nothing\n' % _indent(want)
1691 elif got: 1692 elif got:
1692 return 'Expected nothing\nGot:\n%s' % _indent(got) 1693 return 'Expected nothing\nGot:\n%s' % _indent(got)
(...skipping 666 matching lines...) Expand 10 before | Expand all | Expand 10 after
2359 test_finder = DocTestFinder() 2360 test_finder = DocTestFinder()
2360 2361
2361 module = _normalize_module(module) 2362 module = _normalize_module(module)
2362 tests = test_finder.find(module, globs=globs, extraglobs=extraglobs) 2363 tests = test_finder.find(module, globs=globs, extraglobs=extraglobs)
2363 2364
2364 if not tests and sys.flags.optimize >=2: 2365 if not tests and sys.flags.optimize >=2:
2365 # Skip doctests when running with -O2 2366 # Skip doctests when running with -O2
2366 suite = _DocTestSuite() 2367 suite = _DocTestSuite()
2367 suite.addTest(SkipDocTestCase(module)) 2368 suite.addTest(SkipDocTestCase(module))
2368 return suite 2369 return suite
2369 elif not tests:
2370 # Why do we want to do this? Because it reveals a bug that might
2371 # otherwise be hidden.
2372 # It is probably a bug that this exception is not also raised if the
2373 # number of doctest examples in tests is zero (i.e. if no doctest
2374 # examples were found). However, we should probably not be raising
2375 # an exception at all here, though it is too late to make this change
2376 # for a maintenance release. See also issue #14649.
2377 raise ValueError(module, "has no docstrings")
2378 2370
2379 tests.sort() 2371 tests.sort()
2380 suite = _DocTestSuite() 2372 suite = _DocTestSuite()
2381 2373
2382 for test in tests: 2374 for test in tests:
2383 if len(test.examples) == 0: 2375 if len(test.examples) == 0:
2384 continue 2376 continue
2385 if not test.filename: 2377 if not test.filename:
2386 filename = module.__file__ 2378 filename = module.__file__
2387 if filename[-4:] in (".pyc", ".pyo"): 2379 if filename[-4:] == ".pyc":
2388 filename = filename[:-1] 2380 filename = filename[:-1]
2389 test.filename = filename 2381 test.filename = filename
2390 suite.addTest(DocTestCase(test, **options)) 2382 suite.addTest(DocTestCase(test, **options))
2391 2383
2392 return suite 2384 return suite
2393 2385
2394 class DocFileCase(DocTestCase): 2386 class DocFileCase(DocTestCase):
2395 2387
2396 def id(self): 2388 def id(self):
2397 return '_'.join(self._dt_test.name.split('.')) 2389 return '_'.join(self._dt_test.name.split('.'))
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after
2774 else: 2766 else:
2775 failures, _ = testfile(filename, module_relative=False, 2767 failures, _ = testfile(filename, module_relative=False,
2776 verbose=verbose, optionflags=options) 2768 verbose=verbose, optionflags=options)
2777 if failures: 2769 if failures:
2778 return 1 2770 return 1
2779 return 0 2771 return 0
2780 2772
2781 2773
2782 if __name__ == "__main__": 2774 if __name__ == "__main__":
2783 sys.exit(_test()) 2775 sys.exit(_test())
LEFTRIGHT

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+