mirror of https://github.com/python/cpython
Remove the horrid generators hack from doctest.py. This relies on a
somewhat less horrid hack <wink>: if a module does from __future__ import X then the module dict D is left in a state such that (viewing X as a string) D[X] is getattr(__future__, X) So by examining D for all the names of future features, and making that test for each, we can make a darned good guess as to which future-features were imported by the module. The appropriate flags are then sucked out of the __future__ module, and passed on to compile()'s new optional arguments (PEP 264). Also gave doctest a meaningful __all__, removed the history of changes (CVS serves that purpose now), and removed the __version__ vrbl (similarly; before CVS, it was a reasonable clue, but not anymore).
This commit is contained in:
parent
ec927348c2
commit
4fd9e2fc13
110
Lib/doctest.py
110
Lib/doctest.py
|
@ -1,4 +1,4 @@
|
||||||
# Module doctest version 0.9.7
|
# Module doctest.
|
||||||
# Released to the public domain 16-Jan-2001,
|
# Released to the public domain 16-Jan-2001,
|
||||||
# by Tim Peters (tim.one@home.com).
|
# by Tim Peters (tim.one@home.com).
|
||||||
|
|
||||||
|
@ -294,70 +294,14 @@ ok
|
||||||
Test passed.
|
Test passed.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# 0,0,1 06-Mar-1999
|
__all__ = [
|
||||||
# initial version posted
|
'testmod',
|
||||||
# 0,0,2 06-Mar-1999
|
'run_docstring_examples',
|
||||||
# loosened parsing:
|
'is_private',
|
||||||
# cater to stinkin' tabs
|
'Tester',
|
||||||
# don't insist on a blank after PS2 prefix
|
]
|
||||||
# so trailing "... " line from a compound stmt no longer
|
|
||||||
# breaks if the file gets whitespace-trimmed
|
|
||||||
# better error msgs for inconsistent leading whitespace
|
|
||||||
# 0,9,1 08-Mar-1999
|
|
||||||
# exposed the Tester class and added client methods
|
|
||||||
# plus docstring examples of their use (eww - head-twisting!)
|
|
||||||
# fixed logic error in reporting total # of tests & failures
|
|
||||||
# added __test__ support to testmod (a pale reflection of Christian
|
|
||||||
# Tismer's vision ...)
|
|
||||||
# removed the "deep" argument; fiddle __test__ instead
|
|
||||||
# simplified endcase logic for extracting tests, and running them.
|
|
||||||
# before, if no output was expected but some was produced
|
|
||||||
# anyway via an eval'ed result, the discrepancy wasn't caught
|
|
||||||
# made TestClass private and used __test__ to get at it
|
|
||||||
# many doc updates
|
|
||||||
# speed _SpoofOut for long expected outputs
|
|
||||||
# 0,9,2 09-Mar-1999
|
|
||||||
# throw out comments from examples, enabling use of the much simpler
|
|
||||||
# exec compile(... "single") ...
|
|
||||||
# for simulating the runtime; that barfs on comment-only lines
|
|
||||||
# used the traceback module to do a much better job of reporting
|
|
||||||
# exceptions
|
|
||||||
# run __doc__ values thru str(), "just in case"
|
|
||||||
# privateness of names now determined by an overridable "isprivate"
|
|
||||||
# function
|
|
||||||
# by default a name now considered to be private iff it begins with
|
|
||||||
# an underscore but doesn't both begin & end with two of 'em; so
|
|
||||||
# e.g. Class.__init__ etc are searched now -- as they always
|
|
||||||
# should have been
|
|
||||||
# 0,9,3 18-Mar-1999
|
|
||||||
# added .flush stub to _SpoofOut (JPython buglet diagnosed by
|
|
||||||
# Hugh Emberson)
|
|
||||||
# repaired ridiculous docs about backslashes in examples
|
|
||||||
# minor internal changes
|
|
||||||
# changed source to Unix line-end conventions
|
|
||||||
# moved __test__ logic into new Tester.run__test__ method
|
|
||||||
# 0,9,4 27-Mar-1999
|
|
||||||
# report item name and line # in failing examples
|
|
||||||
# 0,9,5 29-Jun-1999
|
|
||||||
# allow straightforward exceptions in examples - thanks to Mark Hammond!
|
|
||||||
# 0,9,6 16-Jan-2001
|
|
||||||
# fiddling for changes in Python 2.0: some of the embedded docstring
|
|
||||||
# examples no longer worked *exactly* as advertised, due to minor
|
|
||||||
# language changes, and running doctest on itself pointed that out.
|
|
||||||
# Hard to think of a better example of why this is useful <wink>.
|
|
||||||
# 0,9,7 9-Feb-2001
|
|
||||||
# string method conversion
|
|
||||||
|
|
||||||
# XXX Until generators are part of the language, examples in doctest'ed
|
import __future__
|
||||||
# modules will inherit doctest's __future__ settings (see PEP 236 for
|
|
||||||
# more on that). In the absence of a better working idea, the std
|
|
||||||
# test suite needs generators, while the set of doctest'ed modules that
|
|
||||||
# don't use "yield" in a generator context may well be empty. So
|
|
||||||
# enable generators here. This can go away when generators are no
|
|
||||||
# longer optional.
|
|
||||||
from __future__ import generators
|
|
||||||
|
|
||||||
__version__ = 0, 9, 7
|
|
||||||
|
|
||||||
import types
|
import types
|
||||||
_FunctionType = types.FunctionType
|
_FunctionType = types.FunctionType
|
||||||
|
@ -375,8 +319,6 @@ _isEmpty = re.compile(r"\s*$").match
|
||||||
_isComment = re.compile(r"\s*#").match
|
_isComment = re.compile(r"\s*#").match
|
||||||
del re
|
del re
|
||||||
|
|
||||||
__all__ = []
|
|
||||||
|
|
||||||
# Extract interactive examples from a string. Return a list of triples,
|
# Extract interactive examples from a string. Return a list of triples,
|
||||||
# (source, outcome, lineno). "source" is the source code, and ends
|
# (source, outcome, lineno). "source" is the source code, and ends
|
||||||
# with a newline iff the source spans more than one line. "outcome" is
|
# with a newline iff the source spans more than one line. "outcome" is
|
||||||
|
@ -487,7 +429,8 @@ def _tag_out(printer, *tag_msg_pairs):
|
||||||
# stuff to "the real" stdout, and fakeout is an instance of _SpoofOut
|
# stuff to "the real" stdout, and fakeout is an instance of _SpoofOut
|
||||||
# that captures the examples' std output. Return (#failures, #tries).
|
# that captures the examples' std output. Return (#failures, #tries).
|
||||||
|
|
||||||
def _run_examples_inner(out, fakeout, examples, globs, verbose, name):
|
def _run_examples_inner(out, fakeout, examples, globs, verbose, name,
|
||||||
|
compileflags):
|
||||||
import sys, traceback
|
import sys, traceback
|
||||||
OK, BOOM, FAIL = range(3)
|
OK, BOOM, FAIL = range(3)
|
||||||
NADA = "nothing"
|
NADA = "nothing"
|
||||||
|
@ -499,7 +442,8 @@ def _run_examples_inner(out, fakeout, examples, globs, verbose, name):
|
||||||
("Expecting", want or NADA))
|
("Expecting", want or NADA))
|
||||||
fakeout.clear()
|
fakeout.clear()
|
||||||
try:
|
try:
|
||||||
exec compile(source, "<string>", "single") in globs
|
exec compile(source, "<string>", "single",
|
||||||
|
compileflags, 1) in globs
|
||||||
got = fakeout.get()
|
got = fakeout.get()
|
||||||
state = OK
|
state = OK
|
||||||
except:
|
except:
|
||||||
|
@ -538,17 +482,28 @@ def _run_examples_inner(out, fakeout, examples, globs, verbose, name):
|
||||||
|
|
||||||
return failures, len(examples)
|
return failures, len(examples)
|
||||||
|
|
||||||
|
# Get the future-flags associated with the future features that have been
|
||||||
|
# imported into globs.
|
||||||
|
|
||||||
|
def _extract_future_flags(globs):
|
||||||
|
flags = 0
|
||||||
|
for fname in __future__.all_feature_names:
|
||||||
|
feature = globs.get(fname, None)
|
||||||
|
if feature is getattr(__future__, fname):
|
||||||
|
flags |= feature.compiler_flag
|
||||||
|
return flags
|
||||||
|
|
||||||
# Run list of examples, in a shallow copy of context (dict) globs.
|
# Run list of examples, in a shallow copy of context (dict) globs.
|
||||||
# Return (#failures, #tries).
|
# Return (#failures, #tries).
|
||||||
|
|
||||||
def _run_examples(examples, globs, verbose, name):
|
def _run_examples(examples, globs, verbose, name, compileflags):
|
||||||
import sys
|
import sys
|
||||||
saveout = sys.stdout
|
saveout = sys.stdout
|
||||||
globs = globs.copy()
|
globs = globs.copy()
|
||||||
try:
|
try:
|
||||||
sys.stdout = fakeout = _SpoofOut()
|
sys.stdout = fakeout = _SpoofOut()
|
||||||
x = _run_examples_inner(saveout.write, fakeout, examples,
|
x = _run_examples_inner(saveout.write, fakeout, examples,
|
||||||
globs, verbose, name)
|
globs, verbose, name, compileflags)
|
||||||
finally:
|
finally:
|
||||||
sys.stdout = saveout
|
sys.stdout = saveout
|
||||||
# While Python gc can clean up most cycles on its own, it doesn't
|
# While Python gc can clean up most cycles on its own, it doesn't
|
||||||
|
@ -562,7 +517,8 @@ def _run_examples(examples, globs, verbose, name):
|
||||||
globs.clear()
|
globs.clear()
|
||||||
return x
|
return x
|
||||||
|
|
||||||
def run_docstring_examples(f, globs, verbose=0, name="NoName"):
|
def run_docstring_examples(f, globs, verbose=0, name="NoName",
|
||||||
|
compileflags=None):
|
||||||
"""f, globs, verbose=0, name="NoName" -> run examples from f.__doc__.
|
"""f, globs, verbose=0, name="NoName" -> run examples from f.__doc__.
|
||||||
|
|
||||||
Use (a shallow copy of) dict globs as the globals for execution.
|
Use (a shallow copy of) dict globs as the globals for execution.
|
||||||
|
@ -587,7 +543,9 @@ def run_docstring_examples(f, globs, verbose=0, name="NoName"):
|
||||||
e = _extract_examples(doc)
|
e = _extract_examples(doc)
|
||||||
if not e:
|
if not e:
|
||||||
return 0, 0
|
return 0, 0
|
||||||
return _run_examples(e, globs, verbose, name)
|
if compileflags is None:
|
||||||
|
compileflags = _extract_future_flags(globs)
|
||||||
|
return _run_examples(e, globs, verbose, name, compileflags)
|
||||||
|
|
||||||
def is_private(prefix, base):
|
def is_private(prefix, base):
|
||||||
"""prefix, base -> true iff name prefix + "." + base is "private".
|
"""prefix, base -> true iff name prefix + "." + base is "private".
|
||||||
|
@ -724,6 +682,8 @@ see its docs for details.
|
||||||
|
|
||||||
self.name2ft = {} # map name to (#failures, #trials) pair
|
self.name2ft = {} # map name to (#failures, #trials) pair
|
||||||
|
|
||||||
|
self.compileflags = _extract_future_flags(globs)
|
||||||
|
|
||||||
def runstring(self, s, name):
|
def runstring(self, s, name):
|
||||||
"""
|
"""
|
||||||
s, name -> search string s for examples to run, logging as name.
|
s, name -> search string s for examples to run, logging as name.
|
||||||
|
@ -755,7 +715,8 @@ see its docs for details.
|
||||||
f = t = 0
|
f = t = 0
|
||||||
e = _extract_examples(s)
|
e = _extract_examples(s)
|
||||||
if e:
|
if e:
|
||||||
f, t = _run_examples(e, self.globs, self.verbose, name)
|
f, t = _run_examples(e, self.globs, self.verbose, name,
|
||||||
|
self.compileflags)
|
||||||
if self.verbose:
|
if self.verbose:
|
||||||
print f, "of", t, "examples failed in string", name
|
print f, "of", t, "examples failed in string", name
|
||||||
self.__record_outcome(name, f, t)
|
self.__record_outcome(name, f, t)
|
||||||
|
@ -793,7 +754,8 @@ see its docs for details.
|
||||||
"when object.__name__ doesn't exist; " + `object`)
|
"when object.__name__ doesn't exist; " + `object`)
|
||||||
if self.verbose:
|
if self.verbose:
|
||||||
print "Running", name + ".__doc__"
|
print "Running", name + ".__doc__"
|
||||||
f, t = run_docstring_examples(object, self.globs, self.verbose, name)
|
f, t = run_docstring_examples(object, self.globs, self.verbose, name,
|
||||||
|
self.compileflags)
|
||||||
if self.verbose:
|
if self.verbose:
|
||||||
print f, "of", t, "examples failed in", name + ".__doc__"
|
print f, "of", t, "examples failed in", name + ".__doc__"
|
||||||
self.__record_outcome(name, f, t)
|
self.__record_outcome(name, f, t)
|
||||||
|
|
Loading…
Reference in New Issue