[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