Index: Doc/howto/sorting.rst =================================================================== --- Doc/howto/sorting.rst (revision 85914) +++ Doc/howto/sorting.rst (working copy) @@ -57,28 +57,28 @@ as keys. For example: >>> student_tuples = [ - ('john', 'A', 15), - ('jane', 'B', 12), - ('dave', 'B', 10), - ] + ... ('john', 'A', 15), + ... ('jane', 'B', 12), + ... ('dave', 'B', 10), + ... ] >>> sorted(student_tuples, key=lambda student: student[2]) # sort by age [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)] The same technique works for objects with named attributes. For example: >>> class Student: - def __init__(self, name, grade, age): - self.name = name - self.grade = grade - self.age = age - def __repr__(self): - return repr((self.name, self.grade, self.age)) + ... def __init__(self, name, grade, age): + ... self.name = name + ... self.grade = grade + ... self.age = age + ... def __repr__(self): + ... return repr((self.name, self.grade, self.age)) >>> student_objects = [ - Student('john', 'A', 15), - Student('jane', 'B', 12), - Student('dave', 'B', 10), - ] + ... Student('john', 'A', 15), + ... Student('jane', 'B', 12), + ... Student('dave', 'B', 10), + ... ] >>> sorted(student_objects, key=lambda student: student.age) # sort by age [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)] @@ -209,40 +209,41 @@ a positive value for greater-than. For example, we can do: >>> def numeric_compare(x, y): - return x - y + ... return x - y >>> sorted([5, 2, 4, 1, 3], cmp=numeric_compare) [1, 2, 3, 4, 5] Or you can reverse the order of comparison with: >>> def reverse_numeric(x, y): - return y - x + ... return y - x >>> sorted([5, 2, 4, 1, 3], cmp=reverse_numeric) [5, 4, 3, 2, 1] When porting code from Python 2.x to 3.x, the situation can arise when you have the user supplying a comparison function and you need to convert that to a key -function. The following wrapper makes that easy to do:: +function. The following wrapper makes that easy to do: - def cmp_to_key(mycmp): - 'Convert a cmp= function into a key= function' - class K(object): - def __init__(self, obj, *args): - self.obj = obj - def __lt__(self, other): - return mycmp(self.obj, other.obj) < 0 - def __gt__(self, other): - return mycmp(self.obj, other.obj) > 0 - def __eq__(self, other): - return mycmp(self.obj, other.obj) == 0 - def __le__(self, other): - return mycmp(self.obj, other.obj) <= 0 - def __ge__(self, other): - return mycmp(self.obj, other.obj) >= 0 - def __ne__(self, other): - return mycmp(self.obj, other.obj) != 0 - return K + >>> def cmp_to_key(mycmp): + ... 'Convert a cmp= function into a key= function' + ... class K(object): + ... def __init__(self, obj, *args): + ... self.obj = obj + ... def __lt__(self, other): + ... return mycmp(self.obj, other.obj) < 0 + ... def __gt__(self, other): + ... return mycmp(self.obj, other.obj) > 0 + ... def __eq__(self, other): + ... return mycmp(self.obj, other.obj) == 0 + ... def __le__(self, other): + ... return mycmp(self.obj, other.obj) <= 0 + ... def __ge__(self, other): + ... return mycmp(self.obj, other.obj) >= 0 + ... def __ne__(self, other): + ... return mycmp(self.obj, other.obj) != 0 + ... return K + To convert to a key function, just wrap the old comparison function: >>> sorted([5, 2, 4, 1, 3], key=cmp_to_key(reverse_numeric)) Index: Doc/library/fnmatch.rst =================================================================== --- Doc/library/fnmatch.rst (revision 85914) +++ Doc/library/fnmatch.rst (working copy) @@ -81,7 +81,7 @@ >>> >>> regex = fnmatch.translate('*.txt') >>> regex - '.*\\.txt$' + '.*\\.txt\\Z(?ms)' >>> reobj = re.compile(regex) >>> reobj.match('foobar.txt') <_sre.SRE_Match object at 0x...> Index: Doc/library/ftplib.rst =================================================================== --- Doc/library/ftplib.rst (revision 85914) +++ Doc/library/ftplib.rst (working copy) @@ -62,7 +62,7 @@ .. versionadded:: 2.7 - Here's a sample session using the :class:`FTP_TLS` class: + Here's a sample session using the :class:`FTP_TLS` class:: >>> from ftplib import FTP_TLS >>> ftps = FTP_TLS('ftp.python.org') Index: Doc/library/doctest.rst =================================================================== --- Doc/library/doctest.rst (revision 85914) +++ Doc/library/doctest.rst (working copy) @@ -576,6 +576,9 @@ both these variations will work regardless of whether the test is run under Python 2.7 or Python 3.2 (or later versions): + >>> class CustomError(Exception): + ... pass + >>> raise CustomError('message') #doctest: +IGNORE_EXCEPTION_DETAIL Traceback (most recent call last): CustomError: message Index: Doc/library/urlparse.rst =================================================================== --- Doc/library/urlparse.rst (revision 85914) +++ Doc/library/urlparse.rst (working copy) @@ -66,13 +66,13 @@ a relative url. >>> from urlparse import urlparse - >>> urlparse('//www.cwi.nl:80/%7Eguido/Python.html') + >>> urlparse('//www.cwi.nl:80/%7Eguido/Python.html') # doctest: +NORMALIZE_WHITESPACE ParseResult(scheme='', netloc='www.cwi.nl:80', path='/%7Eguido/Python.html', params='', query='', fragment='') - >>> urlparse('www.cwi.nl:80/%7Eguido/Python.html') + >>> urlparse('www.cwi.nl:80/%7Eguido/Python.html') # doctest: +NORMALIZE_WHITESPACE ParseResult(scheme='', netloc='', path='www.cwi.nl:80/%7Eguido/Python.html', params='', query='', fragment='') - >>> urlparse('help/Python.html') + >>> urlparse('help/Python.html') # doctest: +NORMALIZE_WHITESPACE ParseResult(scheme='', netloc='', path='help/Python.html', params='', query='', fragment='') Index: Doc/library/hashlib.rst =================================================================== --- Doc/library/hashlib.rst (revision 85914) +++ Doc/library/hashlib.rst (working copy) @@ -53,9 +53,9 @@ >>> m.digest() '\xbbd\x9c\x83\xdd\x1e\xa5\xc9\xd9\xde\xc9\xa1\x8d\xf0\xff\xe9' >>> m.digest_size - 16 + 16L >>> m.block_size - 64 + 64L More condensed: Index: Doc/library/collections.rst =================================================================== --- Doc/library/collections.rst (revision 85914) +++ Doc/library/collections.rst (working copy) @@ -129,6 +129,7 @@ >>> c = Counter(a=4, b=2, c=0, d=-2) >>> d = Counter(a=1, b=2, c=3, d=4) >>> c.subtract(d) + >>> c Counter({'a': 3, 'b': 0, 'c': -3, 'd': -6}) The usual dictionary methods are available for :class:`Counter` objects @@ -602,19 +603,19 @@ Example: .. doctest:: - :options: +NORMALIZE_WHITESPACE + :options: +NORMALIZE_WHITESPACE,+REPORT_UDIFF >>> Point = namedtuple('Point', 'x y', verbose=True) class Point(tuple): - 'Point(x, y)' + 'Point(x, y)' - __slots__ = () + __slots__ = () - _fields = ('x', 'y') + _fields = ('x', 'y') def __new__(_cls, x, y): - 'Create a new instance of Point(x, y)' - return _tuple.__new__(_cls, (x, y)) + 'Create new instance of Point(x, y)' + return _tuple.__new__(_cls, (x, y)) @classmethod def _make(cls, iterable, new=tuple.__new__, len=len): @@ -622,29 +623,30 @@ result = new(cls, iterable) if len(result) != 2: raise TypeError('Expected 2 arguments, got %d' % len(result)) - return result + return result def __repr__(self): 'Return a nicely formatted representation string' - return 'Point(x=%r, y=%r)' % self + return 'Point(x=%r, y=%r)' % self def _asdict(self): 'Return a new OrderedDict which maps field names to their values' - return OrderedDict(zip(self._fields, self)) + return OrderedDict(zip(self._fields, self)) def _replace(_self, **kwds): 'Return a new Point object replacing specified fields with new values' result = _self._make(map(kwds.pop, ('x', 'y'), _self)) if kwds: raise ValueError('Got unexpected field names: %r' % kwds.keys()) - return result + return result def __getnewargs__(self): - 'Return self as a plain tuple. Used by copy and pickle.' - return tuple(self) + 'Return self as a plain tuple. Used by copy and pickle.' + return tuple(self) x = _property(_itemgetter(0), doc='Alias for field number 0') y = _property(_itemgetter(1), doc='Alias for field number 1') + >>> p = Point(11, y=22) # instantiate with positional or keyword arguments >>> p[0] + p[1] # indexable like the plain tuple (11, 22) Index: Doc/library/argparse.rst =================================================================== --- Doc/library/argparse.rst (revision 85914) +++ Doc/library/argparse.rst (working copy) @@ -7,7 +7,11 @@ .. versionadded:: 2.7 .. sectionauthor:: Steven Bethard +.. testsetup:: default + :hide: + import argparse + The :mod:`argparse` module makes it easy to write user friendly command line interfaces. The program defines what arguments it requires, and :mod:`argparse` will figure out how to parse those out of :data:`sys.argv`. The :mod:`argparse` @@ -685,6 +689,8 @@ :meth:`add_argument` call, and prints version information and exits when invoked. +:: + >>> import argparse >>> parser = argparse.ArgumentParser(prog='PROG') >>> parser.add_argument('--version', action='version', version='%(prog)s 2.0') Index: Doc/includes/cls.py =================================================================== --- Doc/includes/cls.py (revision 0) +++ Doc/includes/cls.py (revision 0) @@ -0,0 +1,2 @@ +class C: + pass Index: Doc/faq/windows.rst =================================================================== --- Doc/faq/windows.rst (revision 85914) +++ Doc/faq/windows.rst (working copy) @@ -464,9 +464,9 @@ drives. >>> import os - >>> os.path.isdir( '\\\\rorschach\\public') + >>> os.path.isdir( '\\\\rorschach\\public') # doctest: +SKIP 0 - >>> os.path.isdir( '\\\\rorschach\\public\\') + >>> os.path.isdir( '\\\\rorschach\\public\\') # doctest: +SKIP 1 It helps to think of share points as being like drive letters. Example:: Index: Doc/faq/programming.rst =================================================================== --- Doc/faq/programming.rst (revision 85914) +++ Doc/faq/programming.rst (working copy) @@ -1137,17 +1137,23 @@ How do I create a multidimensional list? ---------------------------------------- -You probably tried to make a multidimensional array like this:: +You probably tried to make a multidimensional array like this: - A = [[None] * 2] * 3 +.. doctest:: -This looks correct if you print it:: + >>> A = [[None] * 2] * 3 +This looks correct if you print it: + +.. doctest:: + >>> A [[None, None], [None, None], [None, None]] But when you assign a value, it shows up in multiple places: +.. doctest:: + >>> A[0][0] = 5 >>> A [[5, None], [5, None], [5, None]] @@ -1760,17 +1766,21 @@ updated to use the new class definition. This can result in the following paradoxical behaviour: +.. doctest:: + >>> import cls >>> c = cls.C() # Create an instance of C >>> reload(cls) - + >>> isinstance(c, cls.C) # isinstance is false?!? False The nature of the problem is made clear if you print out the class objects: - >>> c.__class__ +.. doctest:: + + >>> c.__class__ # doctest: +SKIP - >>> cls.C + >>> cls.C # doctest: +SKIP Index: Doc/faq/extending.rst =================================================================== --- Doc/faq/extending.rst (revision 85914) +++ Doc/faq/extending.rst (working copy) @@ -163,7 +163,7 @@ >>> sys.stdout = StdoutCatcher() >>> print 'foo' >>> print 'hello world!' - >>> sys.stderr.write(sys.stdout.data) + >>> sys.stderr.write(sys.stdout.data) # doctest: +SKIP foo hello world! @@ -467,7 +467,7 @@ checking the value of sys.maxunicode: >>> import sys - >>> if sys.maxunicode > 65535: + >>> if sys.maxunicode > 65535: # doctest: +SKIP ... print 'UCS4 build' ... else: ... print 'UCS2 build' Index: Doc/conf.py =================================================================== --- Doc/conf.py (revision 85914) +++ Doc/conf.py (working copy) @@ -186,3 +186,8 @@ coverage_ignore_c_items = { # 'cfunction': [...] } + +# doctest settings: + +doctest_path = [os.path.abspath('includes')] +print doctest_path