summaryrefslogtreecommitdiff
path: root/Lib
diff options
context:
space:
mode:
Diffstat (limited to 'Lib')
-rw-r--r--Lib/collections.py9
-rw-r--r--Lib/decimal.py8
-rw-r--r--Lib/difflib.py19
-rw-r--r--Lib/doctest.py27
-rw-r--r--Lib/inspect.py30
-rw-r--r--Lib/test/test_collections.py6
-rw-r--r--Lib/test/test_doctest.py116
-rw-r--r--Lib/test/test_pyclbr.py6
-rw-r--r--Lib/test/test_re.py12
9 files changed, 141 insertions, 92 deletions
diff --git a/Lib/collections.py b/Lib/collections.py
index e1e9d11a6c..78f92ceb54 100644
--- a/Lib/collections.py
+++ b/Lib/collections.py
@@ -117,23 +117,28 @@ if __name__ == '__main__':
# test and demonstrate ability to override methods
class Point(namedtuple('Point', 'x y')):
+ __slots__ = ()
@property
def hypot(self):
return (self.x ** 2 + self.y ** 2) ** 0.5
def __str__(self):
- return 'Point: x=%6.3f y=%6.3f hypot=%6.3f' % (self.x, self.y, self.hypot)
+ return 'Point: x=%6.3f y=%6.3f hypot=%6.3f' % (self.x, self.y, self.hypot)
- for p in Point(3,4), Point(14,5), Point(9./7,6):
+ for p in Point(3, 4), Point(14, 5/7.):
print (p)
class Point(namedtuple('Point', 'x y')):
'Point class with optimized _make() and _replace() without error-checking'
+ __slots__ = ()
_make = classmethod(tuple.__new__)
def _replace(self, _map=map, **kwds):
return self._make(_map(kwds.get, ('x', 'y'), self))
print(Point(11, 22)._replace(x=100))
+ Point3D = namedtuple('Point3D', Point._fields + ('z',))
+ print(Point3D.__doc__)
+
import doctest
TestResults = namedtuple('TestResults', 'failed attempted')
print(TestResults(*doctest.testmod()))
diff --git a/Lib/decimal.py b/Lib/decimal.py
index 1f5ff12962..434930ad32 100644
--- a/Lib/decimal.py
+++ b/Lib/decimal.py
@@ -137,6 +137,12 @@ __all__ = [
import numbers as _numbers
import copy as _copy
+try:
+ from collections import namedtuple as _namedtuple
+ DecimalTuple = _namedtuple('DecimalTuple', 'sign digits exponent')
+except ImportError:
+ DecimalTuple = lambda *args: args
+
# Rounding
ROUND_DOWN = 'ROUND_DOWN'
ROUND_HALF_UP = 'ROUND_HALF_UP'
@@ -841,7 +847,7 @@ class Decimal(_numbers.Real, _numbers.Inexact):
To show the internals exactly as they are.
"""
- return (self._sign, tuple(map(int, self._int)), self._exp)
+ return DecimalTuple(self._sign, tuple(map(int, self._int)), self._exp)
def __repr__(self):
"""Represents the number as an instance of Decimal."""
diff --git a/Lib/difflib.py b/Lib/difflib.py
index 82e3319858..361be6ec14 100644
--- a/Lib/difflib.py
+++ b/Lib/difflib.py
@@ -30,9 +30,12 @@ Class HtmlDiff:
__all__ = ['get_close_matches', 'ndiff', 'restore', 'SequenceMatcher',
'Differ','IS_CHARACTER_JUNK', 'IS_LINE_JUNK', 'context_diff',
- 'unified_diff', 'HtmlDiff']
+ 'unified_diff', 'HtmlDiff', 'Match']
import heapq
+from collections import namedtuple as _namedtuple
+
+Match = _namedtuple('Match', 'a b size')
def _calculate_ratio(matches, length):
if length:
@@ -363,7 +366,7 @@ class SequenceMatcher:
>>> s = SequenceMatcher(None, " abcd", "abcd abcd")
>>> s.find_longest_match(0, 5, 0, 9)
- (0, 4, 5)
+ Match(a=0, b=4, size=5)
If isjunk is defined, first the longest matching block is
determined as above, but with the additional restriction that no
@@ -379,13 +382,13 @@ class SequenceMatcher:
>>> s = SequenceMatcher(lambda x: x==" ", " abcd", "abcd abcd")
>>> s.find_longest_match(0, 5, 0, 9)
- (1, 0, 4)
+ Match(a=1, b=0, size=4)
If no blocks match, return (alo, blo, 0).
>>> s = SequenceMatcher(None, "ab", "c")
>>> s.find_longest_match(0, 2, 0, 1)
- (0, 0, 0)
+ Match(a=0, b=0, size=0)
"""
# CAUTION: stripping common prefix or suffix would be incorrect.
@@ -452,7 +455,7 @@ class SequenceMatcher:
a[besti+bestsize] == b[bestj+bestsize]:
bestsize = bestsize + 1
- return besti, bestj, bestsize
+ return Match(besti, bestj, bestsize)
def get_matching_blocks(self):
"""Return list of triples describing matching subsequences.
@@ -469,8 +472,8 @@ class SequenceMatcher:
triple with n==0.
>>> s = SequenceMatcher(None, "abxcd", "abcd")
- >>> s.get_matching_blocks()
- [(0, 0, 2), (3, 2, 2), (5, 4, 0)]
+ >>> list(s.get_matching_blocks())
+ [Match(a=0, b=0, size=2), Match(a=3, b=2, size=2), Match(a=5, b=4, size=0)]
"""
if self.matching_blocks is not None:
@@ -523,7 +526,7 @@ class SequenceMatcher:
non_adjacent.append( (la, lb, 0) )
self.matching_blocks = non_adjacent
- return self.matching_blocks
+ return map(Match._make, self.matching_blocks)
def get_opcodes(self):
"""Return list of 5-tuples describing how to turn a into b.
diff --git a/Lib/doctest.py b/Lib/doctest.py
index 4a2da324cb..b5fa574a3e 100644
--- a/Lib/doctest.py
+++ b/Lib/doctest.py
@@ -99,6 +99,9 @@ import sys, traceback, inspect, linecache, os, re
import unittest, difflib, pdb, tempfile
import warnings
from io import StringIO
+from collections import namedtuple
+
+TestResults = namedtuple('TestResults', 'failed attempted')
# There are 4 basic classes:
# - Example: a <source, want> pair, plus an intra-docstring line number.
@@ -1024,10 +1027,10 @@ class DocTestRunner:
>>> tests.sort(key = lambda test: test.name)
>>> for test in tests:
... print(test.name, '->', runner.run(test))
- _TestClass -> (0, 2)
- _TestClass.__init__ -> (0, 2)
- _TestClass.get -> (0, 2)
- _TestClass.square -> (0, 1)
+ _TestClass -> TestResults(failed=0, attempted=2)
+ _TestClass.__init__ -> TestResults(failed=0, attempted=2)
+ _TestClass.get -> TestResults(failed=0, attempted=2)
+ _TestClass.square -> TestResults(failed=0, attempted=1)
The `summarize` method prints a summary of all the test cases that
have been run by the runner, and returns an aggregated `(f, t)`
@@ -1042,7 +1045,7 @@ class DocTestRunner:
7 tests in 4 items.
7 passed and 0 failed.
Test passed.
- (0, 7)
+ TestResults(failed=0, attempted=7)
The aggregated number of tried examples and failed examples is
also available via the `tries` and `failures` attributes:
@@ -1285,7 +1288,7 @@ class DocTestRunner:
# Record and return the number of failures and tries.
self.__record_outcome(test, failures, tries)
- return failures, tries
+ return TestResults(failures, tries)
def __record_outcome(self, test, f, t):
"""
@@ -1417,7 +1420,7 @@ class DocTestRunner:
print("***Test Failed***", totalf, "failures.")
elif verbose:
print("Test passed.")
- return totalf, totalt
+ return TestResults(totalf, totalt)
#/////////////////////////////////////////////////////////////////
# Backward compatibility cruft to maintain doctest.master.
@@ -1688,7 +1691,7 @@ class DebugRunner(DocTestRunner):
... ''', {}, 'foo', 'foo.py', 0)
>>> runner.run(test)
- (0, 1)
+ TestResults(failed=0, attempted=1)
>>> test.globs
{}
@@ -1818,7 +1821,7 @@ def testmod(m=None, name=None, globs=None, verbose=None,
else:
master.merge(runner)
- return runner.failures, runner.tries
+ return TestResults(runner.failures, runner.tries)
def testfile(filename, module_relative=True, name=None, package=None,
globs=None, verbose=None, report=True, optionflags=0,
@@ -1939,7 +1942,7 @@ def testfile(filename, module_relative=True, name=None, package=None,
else:
master.merge(runner)
- return runner.failures, runner.tries
+ return TestResults(runner.failures, runner.tries)
def run_docstring_examples(f, globs, verbose=False, name="NoName",
compileflags=None, optionflags=0):
@@ -1998,7 +2001,7 @@ class Tester:
(f,t) = self.testrunner.run(test)
if self.verbose:
print(f, "of", t, "examples failed in string", name)
- return (f,t)
+ return TestResults(f,t)
def rundoc(self, object, name=None, module=None):
f = t = 0
@@ -2007,7 +2010,7 @@ class Tester:
for test in tests:
(f2, t2) = self.testrunner.run(test)
(f,t) = (f+f2, t+t2)
- return (f,t)
+ return TestResults(f,t)
def rundict(self, d, name, module=None):
import types
diff --git a/Lib/inspect.py b/Lib/inspect.py
index c0db4bc193..074754fdfc 100644
--- a/Lib/inspect.py
+++ b/Lib/inspect.py
@@ -31,6 +31,7 @@ __date__ = '1 Jan 2001'
import sys, os, types, re, dis, imp, tokenize, linecache
from operator import attrgetter
+from collections import namedtuple
# ----------------------------------------------------------- type-checking
def ismodule(object):
@@ -208,6 +209,8 @@ def getmembers(object, predicate=None):
results.sort()
return results
+Attribute = namedtuple('Attribute', 'name kind defining_class object')
+
def classify_class_attrs(cls):
"""Return list of attribute-descriptor tuples.
@@ -274,7 +277,7 @@ def classify_class_attrs(cls):
else:
kind = "data"
- result.append((name, kind, homecls, obj))
+ result.append(Attribute(name, kind, homecls, obj))
return result
@@ -362,6 +365,8 @@ def getfile(object):
raise TypeError('arg is not a module, class, method, '
'function, traceback, frame, or code object')
+ModuleInfo = namedtuple('ModuleInfo', 'name suffix mode module_type')
+
def getmoduleinfo(path):
"""Get the module name, suffix, mode, and module type for a given file."""
filename = os.path.basename(path)
@@ -370,7 +375,7 @@ def getmoduleinfo(path):
suffixes.sort() # try longest suffixes first, in case they overlap
for neglen, suffix, mode, mtype in suffixes:
if filename[neglen:] == suffix:
- return filename[:neglen], suffix, mode, mtype
+ return ModuleInfo(filename[:neglen], suffix, mode, mtype)
def getmodulename(path):
"""Return the module name for a given file, or None."""
@@ -668,6 +673,8 @@ def getclasstree(classes, unique=0):
# These constants are from Python's compile.h.
CO_OPTIMIZED, CO_NEWLOCALS, CO_VARARGS, CO_VARKEYWORDS = 1, 2, 4, 8
+Arguments = namedtuple('Arguments', 'args, varargs, varkw')
+
def getargs(co):
"""Get information about the arguments accepted by a code object.
@@ -676,7 +683,7 @@ def getargs(co):
lists. Keyword-only arguments are appended. 'varargs' and 'varkw'
are the names of the * and ** arguments or None."""
args, varargs, kwonlyargs, varkw = _getfullargs(co)
- return args + kwonlyargs, varargs, varkw
+ return Arguments(args + kwonlyargs, varargs, varkw)
def _getfullargs(co):
"""Get information about the arguments accepted by a code object.
@@ -706,6 +713,9 @@ def _getfullargs(co):
varkw = co.co_varnames[nargs]
return args, varargs, kwonlyargs, varkw
+
+ArgSpec = namedtuple('ArgSpec', 'args varargs keywords defaults')
+
def getargspec(func):
"""Get the names and default values of a function's arguments.
@@ -725,7 +735,10 @@ def getargspec(func):
if kwonlyargs or ann:
raise ValueError("Function has keyword-only arguments or annotations"
", use getfullargspec() API which can support them")
- return (args, varargs, varkw, defaults)
+ return ArgSpec(args, varargs, varkw, defaults)
+
+FullArgSpec = namedtuple('FullArgSpec',
+ 'args, varargs, varkw, defaults, kwonlyargs, kwdefaults, annotations')
def getfullargspec(func):
"""Get the names and default values of a function's arguments.
@@ -747,9 +760,11 @@ def getfullargspec(func):
if not isfunction(func):
raise TypeError('arg is not a Python function')
args, varargs, kwonlyargs, varkw = _getfullargs(func.__code__)
- return (args, varargs, varkw, func.__defaults__,
+ return FullArgSpec(args, varargs, varkw, func.__defaults__,
kwonlyargs, func.__kwdefaults__, func.__annotations__)
+ArgInfo = namedtuple('ArgInfo', 'args varargs keywords locals')
+
def getargvalues(frame):
"""Get information about arguments passed into a particular frame.
@@ -859,6 +874,9 @@ def formatargvalues(args, varargs, varkw, locals,
return '(' + ', '.join(specs) + ')'
# -------------------------------------------------- stack frame extraction
+
+Traceback = namedtuple('Traceback', 'filename lineno function code_context index')
+
def getframeinfo(frame, context=1):
"""Get information about a frame or traceback object.
@@ -890,7 +908,7 @@ def getframeinfo(frame, context=1):
else:
lines = index = None
- return (filename, lineno, frame.f_code.co_name, lines, index)
+ return Traceback(filename, lineno, frame.f_code.co_name, lines, index)
def getlineno(frame):
"""Get the line number from a frame object, allowing for optimization."""
diff --git a/Lib/test/test_collections.py b/Lib/test/test_collections.py
index d8cf72ee01..77af0fb93e 100644
--- a/Lib/test/test_collections.py
+++ b/Lib/test/test_collections.py
@@ -1,6 +1,6 @@
"""Unit tests for collections.py."""
-import unittest
+import unittest, doctest
from test import test_support
from collections import namedtuple
from collections import Hashable, Iterable, Iterator
@@ -316,10 +316,12 @@ class TestCollectionABCs(unittest.TestCase):
self.failUnless(issubclass(sample, MutableSequence))
self.failIf(issubclass(str, MutableSequence))
+import doctest, collections
+NamedTupleDocs = doctest.DocTestSuite(module=collections)
def test_main(verbose=None):
import collections as CollectionsModule
- test_classes = [TestNamedTuple, TestOneTrickPonyABCs, TestCollectionABCs]
+ test_classes = [TestNamedTuple, NamedTupleDocs, TestOneTrickPonyABCs, TestCollectionABCs]
test_support.run_unittest(*test_classes)
test_support.run_doctest(CollectionsModule, verbose)
diff --git a/Lib/test/test_doctest.py b/Lib/test/test_doctest.py
index db370b11e1..07e2542a5e 100644
--- a/Lib/test/test_doctest.py
+++ b/Lib/test/test_doctest.py
@@ -658,7 +658,7 @@ given DocTest case in a given namespace (globs). It returns a tuple
of tried tests.
>>> doctest.DocTestRunner(verbose=False).run(test)
- (0, 3)
+ TestResults(failed=0, attempted=3)
If any example produces incorrect output, then the test runner reports
the failure and proceeds to the next example:
@@ -695,7 +695,7 @@ the failure and proceeds to the next example:
Expecting:
6
ok
- (1, 3)
+ TestResults(failed=1, attempted=3)
"""
def verbose_flag(): r"""
The `verbose` flag makes the test runner generate more detailed
@@ -726,7 +726,7 @@ output:
Expecting:
6
ok
- (0, 3)
+ TestResults(failed=0, attempted=3)
If the `verbose` flag is unspecified, then the output will be verbose
iff `-v` appears in sys.argv:
@@ -737,7 +737,7 @@ iff `-v` appears in sys.argv:
>>> # If -v does not appear in sys.argv, then output isn't verbose.
>>> sys.argv = ['test']
>>> doctest.DocTestRunner().run(test)
- (0, 3)
+ TestResults(failed=0, attempted=3)
>>> # If -v does appear in sys.argv, then output is verbose.
>>> sys.argv = ['test', '-v']
@@ -756,7 +756,7 @@ iff `-v` appears in sys.argv:
Expecting:
6
ok
- (0, 3)
+ TestResults(failed=0, attempted=3)
>>> # Restore sys.argv
>>> sys.argv = old_argv
@@ -780,7 +780,7 @@ replaced with any other string:
... '''
>>> test = doctest.DocTestFinder().find(f)[0]
>>> doctest.DocTestRunner(verbose=False).run(test)
- (0, 2)
+ TestResults(failed=0, attempted=2)
An example may not generate output before it raises an exception; if
it does, then the traceback message will not be recognized as
@@ -805,7 +805,7 @@ unexpected exception:
Exception raised:
...
ZeroDivisionError: integer division or modulo by zero
- (1, 2)
+ TestResults(failed=1, attempted=2)
Exception messages may contain newlines:
@@ -819,7 +819,7 @@ Exception messages may contain newlines:
... '''
>>> test = doctest.DocTestFinder().find(f)[0]
>>> doctest.DocTestRunner(verbose=False).run(test)
- (0, 1)
+ TestResults(failed=0, attempted=1)
If an exception is expected, but an exception with the wrong type or
message is raised, then it is reported as a failure:
@@ -844,7 +844,7 @@ message is raised, then it is reported as a failure:
Traceback (most recent call last):
...
ValueError: message
- (1, 1)
+ TestResults(failed=1, attempted=1)
However, IGNORE_EXCEPTION_DETAIL can be used to allow a mismatch in the
detail:
@@ -857,7 +857,7 @@ detail:
... '''
>>> test = doctest.DocTestFinder().find(f)[0]
>>> doctest.DocTestRunner(verbose=False).run(test)
- (0, 1)
+ TestResults(failed=0, attempted=1)
But IGNORE_EXCEPTION_DETAIL does not allow a mismatch in the exception type:
@@ -881,7 +881,7 @@ But IGNORE_EXCEPTION_DETAIL does not allow a mismatch in the exception type:
Traceback (most recent call last):
...
ValueError: message
- (1, 1)
+ TestResults(failed=1, attempted=1)
If an exception is raised but not expected, then it is reported as an
unexpected exception:
@@ -902,7 +902,7 @@ unexpected exception:
Traceback (most recent call last):
...
ZeroDivisionError: integer division or modulo by zero
- (1, 1)
+ TestResults(failed=1, attempted=1)
"""
def optionflags(): r"""
Tests of `DocTestRunner`'s option flag handling.
@@ -921,7 +921,7 @@ and 1/0:
>>> # Without the flag:
>>> test = doctest.DocTestFinder().find(f)[0]
>>> doctest.DocTestRunner(verbose=False).run(test)
- (0, 1)
+ TestResults(failed=0, attempted=1)
>>> # With the flag:
>>> test = doctest.DocTestFinder().find(f)[0]
@@ -936,7 +936,7 @@ and 1/0:
1
Got:
True
- (1, 1)
+ TestResults(failed=1, attempted=1)
The DONT_ACCEPT_BLANKLINE flag disables the match between blank lines
and the '<BLANKLINE>' marker:
@@ -947,7 +947,7 @@ and the '<BLANKLINE>' marker:
>>> # Without the flag:
>>> test = doctest.DocTestFinder().find(f)[0]
>>> doctest.DocTestRunner(verbose=False).run(test)
- (0, 1)
+ TestResults(failed=0, attempted=1)
>>> # With the flag:
>>> test = doctest.DocTestFinder().find(f)[0]
@@ -966,7 +966,7 @@ and the '<BLANKLINE>' marker:
a
<BLANKLINE>
b
- (1, 1)
+ TestResults(failed=1, attempted=1)
The NORMALIZE_WHITESPACE flag causes all sequences of whitespace to be
treated as equal:
@@ -987,13 +987,13 @@ treated as equal:
3
Got:
1 2 3
- (1, 1)
+ TestResults(failed=1, attempted=1)
>>> # With the flag:
>>> test = doctest.DocTestFinder().find(f)[0]
>>> flags = doctest.NORMALIZE_WHITESPACE
>>> doctest.DocTestRunner(verbose=False, optionflags=flags).run(test)
- (0, 1)
+ TestResults(failed=0, attempted=1)
An example from the docs:
>>> print(list(range(20))) #doctest: +NORMALIZE_WHITESPACE
@@ -1018,13 +1018,13 @@ output to match any substring in the actual output:
[0, 1, 2, ..., 14]
Got:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
- (1, 1)
+ TestResults(failed=1, attempted=1)
>>> # With the flag:
>>> test = doctest.DocTestFinder().find(f)[0]
>>> flags = doctest.ELLIPSIS
>>> doctest.DocTestRunner(verbose=False, optionflags=flags).run(test)
- (0, 1)
+ TestResults(failed=0, attempted=1)
... also matches nothing:
@@ -1109,7 +1109,7 @@ and actual outputs to be displayed using a unified diff:
e
f
g
- (1, 1)
+ TestResults(failed=1, attempted=1)
>>> # With the flag:
>>> test = doctest.DocTestFinder().find(f)[0]
@@ -1131,7 +1131,7 @@ and actual outputs to be displayed using a unified diff:
f
g
-h
- (1, 1)
+ TestResults(failed=1, attempted=1)
The REPORT_CDIFF flag causes failures that involve multi-line expected
and actual outputs to be displayed using a context diff:
@@ -1163,7 +1163,7 @@ and actual outputs to be displayed using a context diff:
+ e
f
g
- (1, 1)
+ TestResults(failed=1, attempted=1)
The REPORT_NDIFF flag causes failures to use the difflib.Differ algorithm
@@ -1188,7 +1188,7 @@ marking, as well as interline differences.
? ^
+ a b c d e f g h i j k l m
? + ++ ^
- (1, 1)
+ TestResults(failed=1, attempted=1)
The REPORT_ONLY_FIRST_FAILURE supresses result output after the first
failing example:
@@ -1218,7 +1218,7 @@ failing example:
200
Got:
2
- (3, 5)
+ TestResults(failed=3, attempted=5)
However, output from `report_start` is not supressed:
@@ -1241,7 +1241,7 @@ However, output from `report_start` is not supressed:
200
Got:
2
- (3, 5)
+ TestResults(failed=3, attempted=5)
For the purposes of REPORT_ONLY_FIRST_FAILURE, unexpected exceptions
count as failures:
@@ -1270,7 +1270,7 @@ count as failures:
Exception raised:
...
ValueError: 2
- (3, 5)
+ TestResults(failed=3, attempted=5)
New option flags can also be registered, via register_optionflag(). Here
we reach into doctest's internals a bit.
@@ -1319,7 +1319,7 @@ example with a comment of the form ``# doctest: +OPTION``:
[0, 1, ..., 9]
Got:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
- (1, 2)
+ TestResults(failed=1, attempted=2)
To turn an option off for an example, follow that example with a
comment of the form ``# doctest: -OPTION``:
@@ -1344,7 +1344,7 @@ comment of the form ``# doctest: -OPTION``:
[0, 1, ..., 9]
Got:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
- (1, 2)
+ TestResults(failed=1, attempted=2)
Option directives affect only the example that they appear with; they
do not change the options for surrounding examples:
@@ -1378,7 +1378,7 @@ do not change the options for surrounding examples:
[0, 1, ..., 9]
Got:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
- (2, 3)
+ TestResults(failed=2, attempted=3)
Multiple options may be modified by a single option directive. They
may be separated by whitespace, commas, or both:
@@ -1401,7 +1401,7 @@ may be separated by whitespace, commas, or both:
[0, 1, ..., 9]
Got:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
- (1, 2)
+ TestResults(failed=1, attempted=2)
>>> def f(x): r'''
... >>> print(list(range(10))) # Should fail
@@ -1421,7 +1421,7 @@ may be separated by whitespace, commas, or both:
[0, 1, ..., 9]
Got:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
- (1, 2)
+ TestResults(failed=1, attempted=2)
>>> def f(x): r'''
... >>> print(list(range(10))) # Should fail
@@ -1441,7 +1441,7 @@ may be separated by whitespace, commas, or both:
[0, 1, ..., 9]
Got:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
- (1, 2)
+ TestResults(failed=1, attempted=2)
The option directive may be put on the line following the source, as
long as a continuation prompt is used:
@@ -1453,7 +1453,7 @@ long as a continuation prompt is used:
... '''
>>> test = doctest.DocTestFinder().find(f)[0]
>>> doctest.DocTestRunner(verbose=False).run(test)
- (0, 1)
+ TestResults(failed=0, attempted=1)
For examples with multi-line source, the option directive may appear
at the end of any line:
@@ -1469,7 +1469,7 @@ at the end of any line:
... '''
>>> test = doctest.DocTestFinder().find(f)[0]
>>> doctest.DocTestRunner(verbose=False).run(test)
- (0, 2)
+ TestResults(failed=0, attempted=2)
If more than one line of an example with multi-line source has an
option directive, then they are combined:
@@ -1482,7 +1482,7 @@ option directive, then they are combined:
... '''
>>> test = doctest.DocTestFinder().find(f)[0]
>>> doctest.DocTestRunner(verbose=False).run(test)
- (0, 1)
+ TestResults(failed=0, attempted=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
@@ -1616,7 +1616,7 @@ def test_pdb_set_trace():
(Pdb) print(x)
42
(Pdb) continue
- (0, 2)
+ TestResults(failed=0, attempted=2)
You can also put pdb.set_trace in a function called from a test:
@@ -1652,7 +1652,7 @@ def test_pdb_set_trace():
(Pdb) print(x)
1
(Pdb) continue
- (0, 2)
+ TestResults(failed=0, attempted=2)
During interactive debugging, source code is shown, even for
doctest examples:
@@ -1709,7 +1709,7 @@ def test_pdb_set_trace():
Expected nothing
Got:
9
- (1, 3)
+ TestResults(failed=1, attempted=3)
"""
def test_pdb_set_trace_nested():
@@ -1795,7 +1795,7 @@ def test_pdb_set_trace_nested():
(Pdb) print(foo)
*** NameError: NameError("name 'foo' is not defined",)
(Pdb) continue
- (0, 2)
+ TestResults(failed=0, attempted=2)
"""
def test_DocTestSuite():
@@ -2156,7 +2156,7 @@ calling module. The return value is (#failures, #tests).
1 items had failures:
1 of 2 in test_doctest.txt
***Test Failed*** 1 failures.
- (1, 2)
+ TestResults(failed=1, attempted=2)
>>> doctest.master = None # Reset master.
(Note: we'll be clearing doctest.master after each call to
@@ -2167,7 +2167,7 @@ Globals may be specified with the `globs` and `extraglobs` parameters:
>>> globs = {'favorite_color': 'blue'}
>>> doctest.testfile('test_doctest.txt', globs=globs)
- (0, 2)
+ TestResults(failed=0, attempted=2)
>>> doctest.master = None # Reset master.
>>> extraglobs = {'favorite_color': 'red'}
@@ -2185,7 +2185,7 @@ Globals may be specified with the `globs` and `extraglobs` parameters:
1 items had failures:
1 of 2 in test_doctest.txt
***Test Failed*** 1 failures.
- (1, 2)
+ TestResults(failed=1, attempted=2)
>>> doctest.master = None # Reset master.
The file may be made relative to a given module or package, using the
@@ -2193,7 +2193,7 @@ optional `module_relative` parameter:
>>> doctest.testfile('test_doctest.txt', globs=globs,
... module_relative='test')
- (0, 2)
+ TestResults(failed=0, attempted=2)
>>> doctest.master = None # Reset master.
Verbosity can be increased with the optional `verbose` paremter:
@@ -2219,7 +2219,7 @@ Verbosity can be increased with the optional `verbose` paremter:
2 tests in 1 items.
2 passed and 0 failed.
Test passed.
- (0, 2)
+ TestResults(failed=0, attempted=2)
>>> doctest.master = None # Reset master.
The name of the test may be specified with the optional `name`
@@ -2230,7 +2230,7 @@ parameter:
**********************************************************************
File "...", line 6, in newname
...
- (1, 2)
+ TestResults(failed=1, attempted=2)
>>> doctest.master = None # Reset master.
The summary report may be supressed with the optional `report`
@@ -2245,7 +2245,7 @@ parameter:
Exception raised:
...
NameError: name 'favorite_color' is not defined
- (1, 2)
+ TestResults(failed=1, attempted=2)
>>> doctest.master = None # Reset master.
The optional keyword argument `raise_on_error` can be used to raise an
@@ -2277,11 +2277,11 @@ using the optional keyword argument `encoding`:
1 items had failures:
2 of 2 in test_doctest4.txt
***Test Failed*** 2 failures.
- (2, 2)
+ TestResults(failed=2, attempted=2)
>>> doctest.master = None # Reset master.
>>> doctest.testfile('test_doctest4.txt', encoding='utf-8')
- (0, 2)
+ TestResults(failed=0, attempted=2)
>>> doctest.master = None # Reset master.
"""
@@ -2311,15 +2311,15 @@ Expected:
42
Got:
84
-(1, 2)
+TestResults(failed=1, attempted=2)
>>> t.runstring(">>> x = x * 2\n>>> print(x)\n84\n", 'example2')
-(0, 2)
+TestResults(failed=0, attempted=2)
>>> t.summarize()
**********************************************************************
1 items had failures:
1 of 2 in XYZ
***Test Failed*** 1 failures.
-(1, 4)
+TestResults(failed=1, attempted=4)
>>> t.summarize(verbose=1)
1 items passed all tests:
2 tests in example2
@@ -2329,7 +2329,7 @@ Got:
4 tests in 2 items.
3 passed and 1 failed.
***Test Failed*** 1 failures.
-(1, 4)
+TestResults(failed=1, attempted=4)
"""
def old_test2(): r"""
@@ -2353,7 +2353,7 @@ def old_test2(): r"""
3
ok
0 of 2 examples failed in string Example
- (0, 2)
+ TestResults(failed=0, attempted=2)
"""
def old_test3(): r"""
@@ -2366,7 +2366,7 @@ def old_test3(): r"""
... return 32
...
>>> t.rundoc(_f) # expect 0 failures in 1 example
- (0, 1)
+ TestResults(failed=0, attempted=1)
"""
def old_test4(): """
@@ -2396,19 +2396,19 @@ def old_test4(): """
>>> from doctest import Tester
>>> t = Tester(globs={}, verbose=0)
>>> t.rundict(m1.__dict__, "rundict_test", m1) # f2 and g2 and h2 skipped
- (0, 4)
+ TestResults(failed=0, attempted=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)
+ TestResults(failed=0, attempted=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)
+ TestResults(failed=0, attempted=4)
"""
######################################################################
diff --git a/Lib/test/test_pyclbr.py b/Lib/test/test_pyclbr.py
index b88cb7e90b..5d46db1b6a 100644
--- a/Lib/test/test_pyclbr.py
+++ b/Lib/test/test_pyclbr.py
@@ -40,7 +40,7 @@ class PyclbrTest(TestCase):
if key in ignore: return
if key not in obj:
print("***",key, file=sys.stderr)
- self.failUnless(key in obj)
+ self.failUnless(key in obj, "%r in %r" % (key, obj))
def assertEqualsOrIgnored(self, a, b, ignore):
''' succeed iff a == b or a in ignore or b in ignore '''
@@ -140,9 +140,9 @@ class PyclbrTest(TestCase):
def test_easy(self):
self.checkModule('pyclbr')
- self.checkModule('doctest')
+ self.checkModule('doctest', ignore=("TestResults",))
self.checkModule('rfc822')
- self.checkModule('difflib')
+ self.checkModule('difflib', ignore=("Match",))
def test_decorators(self):
# XXX: See comment in pyclbr_input.py for a test that would fail
diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py
index 866f5986a7..28e508c7d8 100644
--- a/Lib/test/test_re.py
+++ b/Lib/test/test_re.py
@@ -661,6 +661,18 @@ class ReTests(unittest.TestCase):
q = p.match(upper_char)
self.assertNotEqual(q, None)
+ def test_dollar_matches_twice(self):
+ "$ matches the end of string, and just before the terminating \n"
+ pattern = re.compile('$')
+ self.assertEqual(pattern.sub('#', 'a\nb\n'), 'a\nb#\n#')
+ self.assertEqual(pattern.sub('#', 'a\nb\nc'), 'a\nb\nc#')
+ self.assertEqual(pattern.sub('#', '\n'), '#\n#')
+
+ pattern = re.compile('$', re.MULTILINE)
+ self.assertEqual(pattern.sub('#', 'a\nb\n' ), 'a#\nb#\n#' )
+ self.assertEqual(pattern.sub('#', 'a\nb\nc'), 'a#\nb#\nc#')
+ self.assertEqual(pattern.sub('#', '\n'), '#\n#')
+
def run_re_tests():
from test.re_tests import benchmarks, tests, SUCCEED, FAIL, SYNTAX_ERROR