[Python-checkins] python/dist/src/Lib doctest.py, 1.36.2.11, 1.36.2.12

edloper at users.sourceforge.net edloper at users.sourceforge.net
Wed Aug 4 03:06:43 CEST 2004


Update of /cvsroot/python/python/dist/src/Lib
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19199
Modified Files:
 Tag: tim-doctest-branch
	doctest.py 
Log Message:
- Added "globs" as an instance variable of DocTest.
- Added globs and extraglobs arguments to DocTestFinder.find()
- Removed globs and extraglobs arguments to DocTestRunner.run()
- Renamed DocTestRunner._optionflags to DocTestRunner.optionflags
Index: doctest.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/doctest.py,v
retrieving revision 1.36.2.11
retrieving revision 1.36.2.12
diff -C2 -d -r1.36.2.11 -r1.36.2.12
*** doctest.py	3 Aug 2004 21:22:41 -0000	1.36.2.11
--- doctest.py	4 Aug 2004 01:06:40 -0000	1.36.2.12
***************
*** 493,496 ****
--- 493,499 ----
 - examples: the list of examples.
 
+ - globs: The namespace (aka globals) that the examples should
+ be run in.
+ 
 - name: A name identifying the DocTest (typically, the name of
 the object whose docstring this DocTest was extracted from).
***************
*** 503,510 ****
 beginning of the file.
 """
! def __init__(self, docstring, name, filename, lineno):
 """
 Create a new DocTest, by extracting examples from `docstring`.
 """
 # Store identifying information
 self.name = name
--- 506,516 ----
 beginning of the file.
 """
! def __init__(self, docstring, globs, name, filename, lineno):
 """
 Create a new DocTest, by extracting examples from `docstring`.
+ The DocTest's globals are initialized with a copy of `globs`.
 """
+ # Store a copy of the globals
+ self.globs = globs.copy()
 # Store identifying information
 self.name = name
***************
*** 651,659 ****
 self._recurse = recurse
 
! def find(self, obj, name=None, module=None):
 """
 Return a list of the DocTests that are defined by the given
 object's docstring, or by any of its contained objects'
 docstrings.
 """
 # If name was not specified, then extract it from the object.
--- 657,674 ----
 self._recurse = recurse
 
! def find(self, obj, name=None, module=None, globs=None,
! extraglobs=None):
 """
 Return a list of the DocTests that are defined by the given
 object's docstring, or by any of its contained objects'
 docstrings.
+ 
+ The globals for each DocTest is formed by combining `globs`
+ and `extraglobs` (bindings in `extraglobs` override bindings
+ in `globs`). A new copy of the globals dictionary is created
+ for each DocTest. If `globs` is not specified, then it
+ defaults to the module's `__dict__`, if specified, or {}
+ otherwise. If `extraglobs` is not specified, then it defaults
+ to {}.
 """
 # If name was not specified, then extract it from the object.
***************
*** 671,675 ****
 module = inspect.getmodule(obj)
 
- 
 # This is a hack to help Tester.rundict. Setting module=None
 # in Tester.rundict should make the tester ignore which module
--- 686,689 ----
***************
*** 694,700 ****
 source_lines = None
 
 # Recursively expore `obj`, extracting DocTests.
 tests = []
! self._find(tests, obj, name, module, source_lines, {})
 return tests
 
--- 708,725 ----
 source_lines = None
 
+ # Initialize globals, and merge in extraglobs.
+ if globs is None:
+ if module is None:
+ globs = {}
+ else:
+ globs = module.__dict__.copy()
+ else:
+ globs = globs.copy()
+ if extraglobs is not None:
+ globs.update(extraglobs)
+ 
 # Recursively expore `obj`, extracting DocTests.
 tests = []
! self._find(tests, obj, name, module, source_lines, globs, {})
 return tests
 
***************
*** 724,728 ****
 raise ValueError("object must be a class or function")
 
! def _find(self, tests, obj, name, module, source_lines, seen):
 """
 Find tests for the given object and any contained objects, and
--- 749,753 ----
 raise ValueError("object must be a class or function")
 
! def _find(self, tests, obj, name, module, source_lines, globs, seen):
 """
 Find tests for the given object and any contained objects, and
***************
*** 738,742 ****
 
 # Find a test for this object, and add it to the list of tests.
! test = self._get_test(obj, name, module, source_lines)
 if test is not None:
 tests.append(test)
--- 763,767 ----
 
 # Find a test for this object, and add it to the list of tests.
! test = self._get_test(obj, name, module, globs, source_lines)
 if test is not None:
 tests.append(test)
***************
*** 753,757 ****
 and self._from_module(module, val)):
 self._find(tests, val, valname, module,
! source_lines, seen)
 
 # Look for tests in a module's __test__ dictionary.
--- 778,782 ----
 and self._from_module(module, val)):
 self._find(tests, val, valname, module,
! source_lines, globs, seen)
 
 # Look for tests in a module's __test__ dictionary.
***************
*** 770,774 ****
 (type(val),))
 valname = '%s.%s' % (name, valname)
! self._find(tests, val, valname, module, source_lines, seen)
 
 # Look for tests in a class's contained objects.
--- 795,800 ----
 (type(val),))
 valname = '%s.%s' % (name, valname)
! self._find(tests, val, valname, module,
! source_lines, globs, seen)
 
 # Look for tests in a class's contained objects.
***************
*** 789,795 ****
 valname = '%s.%s' % (name, valname)
 self._find(tests, val, valname, module,
! source_lines, seen)
 
! def _get_test(self, obj, name, module, source_lines):
 """
 Return a DocTest for the given object, if it defines a docstring;
--- 815,821 ----
 valname = '%s.%s' % (name, valname)
 self._find(tests, val, valname, module,
! source_lines, globs, seen)
 
! def _get_test(self, obj, name, module, globs, source_lines):
 """
 Return a DocTest for the given object, if it defines a docstring;
***************
*** 820,824 ****
 else:
 filename = getattr(module, '__file__', module.__name__)
! return DocTest(docstring, name, filename, lineno)
 
 def _find_lineno(self, obj, source_lines):
--- 846,850 ----
 else:
 filename = getattr(module, '__file__', module.__name__)
! return DocTest(docstring, globs, name, filename, lineno)
 
 def _find_lineno(self, obj, source_lines):
***************
*** 887,891 ****
 >>> runner = DocTestRunner(verbose=False)
 >>> for test in tests:
! ... print runner.run(test, globals())
 (0, 2)
 (0, 1)
--- 913,917 ----
 >>> runner = DocTestRunner(verbose=False)
 >>> for test in tests:
! ... print runner.run(test)
 (0, 2)
 (0, 1)
***************
*** 953,957 ****
 verbose = '-v' in sys.argv
 self._verbose = verbose
! self._optionflags = optionflags
 
 # Keep track of the examples we've run.
--- 979,983 ----
 verbose = '-v' in sys.argv
 self._verbose = verbose
! self.optionflags = optionflags
 
 # Keep track of the examples we've run.
***************
*** 986,990 ****
 # The values True and False replaced 1 and 0 as the return
 # value for boolean comparisons in Python 2.3.
! if not (self._optionflags & DONT_ACCEPT_TRUE_FOR_1):
 if (got,want) == ("True\n", "1\n"):
 return True
--- 1012,1016 ----
 # The values True and False replaced 1 and 0 as the return
 # value for boolean comparisons in Python 2.3.
! if not (self.optionflags & DONT_ACCEPT_TRUE_FOR_1):
 if (got,want) == ("True\n", "1\n"):
 return True
***************
*** 994,998 ****
 # <BLANKLINE> can be used as a special sequence to signify a
 # blank line, unless the DONT_ACCEPT_BLANKLINE flag is used.
! if not (self._optionflags & DONT_ACCEPT_BLANKLINE):
 # Replace <BLANKLINE> in want with a blank line.
 want = re.sub('(?m)^%s\s*?$' % re.escape(BLANKLINE_MARKER),
--- 1020,1024 ----
 # <BLANKLINE> can be used as a special sequence to signify a
 # blank line, unless the DONT_ACCEPT_BLANKLINE flag is used.
! if not (self.optionflags & DONT_ACCEPT_BLANKLINE):
 # Replace <BLANKLINE> in want with a blank line.
 want = re.sub('(?m)^%s\s*?$' % re.escape(BLANKLINE_MARKER),
***************
*** 1007,1011 ****
 # contents of whitespace strings. Note that this can be used
 # in conjunction with the ELLISPIS flag.
! if (self._optionflags & NORMALIZE_WHITESPACE):
 got = ' '.join(got.split())
 want = ' '.join(want.split())
--- 1033,1037 ----
 # contents of whitespace strings. Note that this can be used
 # in conjunction with the ELLISPIS flag.
! if (self.optionflags & NORMALIZE_WHITESPACE):
 got = ' '.join(got.split())
 want = ' '.join(want.split())
***************
*** 1016,1020 ****
 # match any substring in `got`. We implement this by
 # transforming `want` into a regular expression.
! if (self._optionflags & ELLIPSIS):
 # Escape any special regexp characters
 want_re = re.escape(want)
--- 1042,1046 ----
 # match any substring in `got`. We implement this by
 # transforming `want` into a regular expression.
! if (self.optionflags & ELLIPSIS):
 # Escape any special regexp characters
 want_re = re.escape(want)
***************
*** 1038,1042 ****
 # If <BLANKLINE>s are being used, then replace <BLANKLINE>
 # with blank lines in the expected output string.
! if not (self._optionflags & DONT_ACCEPT_BLANKLINE):
 want = re.sub('(?m)^%s$' % re.escape(BLANKLINE_MARKER), '', want)
 
--- 1064,1068 ----
 # If <BLANKLINE>s are being used, then replace <BLANKLINE>
 # with blank lines in the expected output string.
! if not (self.optionflags & DONT_ACCEPT_BLANKLINE):
 want = re.sub('(?m)^%s$' % re.escape(BLANKLINE_MARKER), '', want)
 
***************
*** 1044,1059 ****
 # or expected outputs are too short, or if the expected output
 # contains an ellipsis marker.
! if ((self._optionflags & (UNIFIED_DIFF | CONTEXT_DIFF)) and
 want.count('\n') > 2 and got.count('\n') > 2 and
! not (self._optionflags & ELLIPSIS and '...' in want)):
 # Split want & got into lines.
 want_lines = [l+'\n' for l in want.split('\n')]
 got_lines = [l+'\n' for l in got.split('\n')]
 # Use difflib to find their differences.
! if self._optionflags & UNIFIED_DIFF:
 diff = difflib.unified_diff(want_lines, got_lines, n=2,
 fromfile='Expected', tofile='Got')
 kind = 'unified'
! elif self._optionflags & CONTEXT_DIFF:
 diff = difflib.context_diff(want_lines, got_lines, n=2,
 fromfile='Expected', tofile='Got')
--- 1070,1085 ----
 # or expected outputs are too short, or if the expected output
 # contains an ellipsis marker.
! if ((self.optionflags & (UNIFIED_DIFF | CONTEXT_DIFF)) and
 want.count('\n') > 2 and got.count('\n') > 2 and
! not (self.optionflags & ELLIPSIS and '...' in want)):
 # Split want & got into lines.
 want_lines = [l+'\n' for l in want.split('\n')]
 got_lines = [l+'\n' for l in got.split('\n')]
 # Use difflib to find their differences.
! if self.optionflags & UNIFIED_DIFF:
 diff = difflib.unified_diff(want_lines, got_lines, n=2,
 fromfile='Expected', tofile='Got')
 kind = 'unified'
! elif self.optionflags & CONTEXT_DIFF:
 diff = difflib.context_diff(want_lines, got_lines, n=2,
 fromfile='Expected', tofile='Got')
***************
*** 1165,1182 ****
 raise ValueError('Bad doctest option directive: '+flag)
 if flag[0] == '+':
! self._optionflags |= OPTIONFLAGS_BY_NAME[flag[1:]]
 else:
! self._optionflags &= ~OPTIONFLAGS_BY_NAME[flag[1:]]
 return True
 
! def __run(self, test, globs, compileflags, out):
 """
! Run the examples in `test`, in the namespace `globs`. Write
! the outcome of each example with one of the
! `DocTestRunnre.report_*` methods, using the writer function
! `out`. `compileflags` is the set of compiler flags that
! should be used to execute examples. Return a tuple `(f, t)`,
! where `t` is the number of examples tried, and `f` is the
! number of examples that failed.
 """
 # Keep track of the number of failures and tries.
--- 1191,1208 ----
 raise ValueError('Bad doctest option directive: '+flag)
 if flag[0] == '+':
! self.optionflags |= OPTIONFLAGS_BY_NAME[flag[1:]]
 else:
! self.optionflags &= ~OPTIONFLAGS_BY_NAME[flag[1:]]
 return True
 
! def __run(self, test, compileflags, out):
 """
! Run the examples in `test`. Write the outcome of each example
! with one of the `DocTestRunner.report_*` methods, using the
! writer function `out`. `compileflags` is the set of compiler
! flags that should be used to execute examples. Return a tuple
! `(f, t)`, where `t` is the number of examples tried, and `f`
! is the number of examples that failed. The examples are run
! in the namespace `test.globs`.
 """
 # Keep track of the number of failures and tries.
***************
*** 1185,1189 ****
 # Save the option flags (since doctest directives can be used
 # to modify them).
! original_optionflags = self._optionflags
 
 # Process each example.
--- 1211,1215 ----
 # Save the option flags (since doctest directives can be used
 # to modify them).
! original_optionflags = self.optionflags
 
 # Process each example.
***************
*** 1207,1211 ****
 # append one (it never hurts).
 exec compile(example.source + '\n', "<string>", "single",
! compileflags, 1) in globs
 exception = None
 except KeyboardInterrupt:
--- 1233,1237 ----
 # append one (it never hurts).
 exec compile(example.source + '\n', "<string>", "single",
! compileflags, 1) in test.globs
 exception = None
 except KeyboardInterrupt:
***************
*** 1258,1262 ****
 
 # Restore the option flags (in case they were modified)
! self._optionflags = original_optionflags
 
 # Record and return the number of failures and tries.
--- 1284,1288 ----
 
 # Restore the option flags (in case they were modified)
! self.optionflags = original_optionflags
 
 # Record and return the number of failures and tries.
***************
*** 1274,1288 ****
 self.tries += t
 
! def run(self, test, globs, extraglobs=None, compileflags=None, out=None):
 """
 Run the examples in `test`, and display the results using the
 writer function `out`.
 
! The examples are all run in a single namespace, which is
! created by combining `globs` and `extraglobs` (bindings in
! `extraglobs` override bindings in `globs`). Shallow changes
! to this namespace by the examples will not affect `globs` or
! `extraglobs`; but changes to objects contained in `globs` or
! extraglobs` will be visible.
 
 `compileflags` gives the set of flags that should be used by
--- 1300,1313 ----
 self.tries += t
 
! def run(self, test, compileflags=None, out=None, clear_globs=True):
 """
 Run the examples in `test`, and display the results using the
 writer function `out`.
 
! The examples are run in the namespace `test.globs`. If
! `clear_globs` is true (the default), then this namespace will
! be cleared after the test runs, to help with garbage
! collection. If you would like to examine the namespace after
! the test completes, then use `clear_globs=False`.
 
 `compileflags` gives the set of flags that should be used by
***************
*** 1296,1309 ****
 """
 if compileflags is None:
! compileflags = _extract_future_flags(globs)
 if out is None:
 out = sys.stdout.write
 saveout = sys.stdout
! globs = globs.copy()
! if extraglobs is not None:
! globs.update(extraglobs)
 try:
 sys.stdout = self._fakeout
! return self.__run(test, globs, compileflags, out)
 finally:
 sys.stdout = saveout
--- 1321,1332 ----
 """
 if compileflags is None:
! compileflags = _extract_future_flags(test.globs)
 if out is None:
 out = sys.stdout.write
 saveout = sys.stdout
! 
 try:
 sys.stdout = self._fakeout
! return self.__run(test, compileflags, out)
 finally:
 sys.stdout = saveout
***************
*** 1316,1320 ****
 # help to break other kinds of cycles, and even for cycles that
 # gc can break itself it's better to break them ASAP.
! globs.clear()
 
 #/////////////////////////////////////////////////////////////////
--- 1339,1344 ----
 # help to break other kinds of cycles, and even for cycles that
 # gc can break itself it's better to break them ASAP.
! if clear_globs:
! test.globs.clear()
 
 #/////////////////////////////////////////////////////////////////
***************
*** 1487,1499 ****
 name = m.__name__
 
- # If globals were not specified, then default to the module.
- if globs is None:
- globs = m.__dict__
- 
 # Find, parse, and run all tests in the given module.
 finder = DocTestFinder(namefilter=isprivate)
 runner = DocTestRunner(verbose=verbose, optionflags=optionflags)
! for test in finder.find(m, name):
! runner.run(test, globs=m.__dict__, extraglobs=extraglobs)
 
 if report:
--- 1511,1519 ----
 name = m.__name__
 
 # Find, parse, and run all tests in the given module.
 finder = DocTestFinder(namefilter=isprivate)
 runner = DocTestRunner(verbose=verbose, optionflags=optionflags)
! for test in finder.find(m, name, globs=globs, extraglobs=extraglobs):
! runner.run(test)
 
 if report:
***************
*** 1522,1527 ****
 finder = DocTestFinder(verbose=verbose, recurse=False)
 runner = DocTestRunner(verbose=verbose, optionflags=optionflags)
! for test in finder.find(f, name):
! runner.run(test, globs=globs, compileflags=compileflags)
 
 ######################################################################
--- 1542,1547 ----
 finder = DocTestFinder(verbose=verbose, recurse=False)
 runner = DocTestRunner(verbose=verbose, optionflags=optionflags)
! for test in finder.find(f, name, globs=globs):
! runner.run(test, compileflags=compileflags)
 
 ######################################################################
***************
*** 1551,1558 ****
 
 def runstring(self, s, name):
! test = DocTest(s, name, None, None)
 if self.verbose:
 print "Running string", name
! (f,t) = self.testrunner.run(test, globs=self.globs)
 if self.verbose:
 print f, "of", t, "examples failed in string", name
--- 1571,1578 ----
 
 def runstring(self, s, name):
! test = DocTest(s, self.globs, name, None, None)
 if self.verbose:
 print "Running string", name
! (f,t) = self.testrunner.run(test)
 if self.verbose:
 print f, "of", t, "examples failed in string", name
***************
*** 1561,1567 ****
 def rundoc(self, object, name=None, module=None):
 f = t = 0
! tests = self.testfinder.find(object, name, module=module)
 for test in tests:
! (f2, t2) = self.testrunner.run(test, globs=self.globs)
 (f,t) = (f+f2, t+t2)
 return (f,t)
--- 1581,1588 ----
 def rundoc(self, object, name=None, module=None):
 f = t = 0
! tests = self.testfinder.find(object, name, module=module,
! globs=self.globs)
 for test in tests:
! (f2, t2) = self.testrunner.run(test)
 (f,t) = (f+f2, t+t2)
 return (f,t)
***************
*** 1599,1609 ****
 """
 
! def __init__(self, test_runner, test, globs, extraglobs=None,
 setUp=None, tearDown=None):
 unittest.TestCase.__init__(self)
 self.__test_runner = test_runner
 self.__test = test
- self.__globs = globs
- self.__extraglobs = extraglobs
 self.__setUp = setUp
 self.__tearDown = tearDown
--- 1620,1628 ----
 """
 
! def __init__(self, test_runner, test,
 setUp=None, tearDown=None):
 unittest.TestCase.__init__(self)
 self.__test_runner = test_runner
 self.__test = test
 self.__setUp = setUp
 self.__tearDown = tearDown
***************
*** 1623,1629 ****
 try:
 self.__test_runner.DIVIDER = "-"*70
! failures, tries = self.__test_runner.run(test, self.__globs,
! self.__extraglobs,
! out=new.write)
 finally:
 sys.stdout = old
--- 1642,1646 ----
 try:
 self.__test_runner.DIVIDER = "-"*70
! failures, tries = self.__test_runner.run(test, out=new.write)
 finally:
 sys.stdout = old
***************
*** 1688,1692 ****
 else:
 module = _normalize_module(module)
! tests = test_finder.find(module)
 if globs is None:
 globs = module.__dict__
--- 1705,1709 ----
 else:
 module = _normalize_module(module)
! tests = test_finder.find(module, globs=globs, extraglobs=extraglobs)
 if globs is None:
 globs = module.__dict__
***************
*** 1705,1710 ****
 filename = filename[:-1]
 test.filename = filename
! suite.addTest(DocTestTestCase(test_runner, test, globs,
! extraglobs, setUp, tearDown))
 
 return suite
--- 1722,1727 ----
 filename = filename[:-1]
 test.filename = filename
! suite.addTest(DocTestTestCase(test_runner, test,
! setUp, tearDown))
 
 return suite
***************
*** 1752,1756 ****
 The string is provided directly
 """
! test = DocTest(src, 'debug', None, None)
 
 testsrc = '\n'.join([
--- 1769,1773 ----
 The string is provided directly
 """
! test = DocTest(src, globs or {}, 'debug', None, None)
 
 testsrc = '\n'.join([


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /