Index: Doc/whatsnew/2.7.rst =================================================================== --- Doc/whatsnew/2.7.rst (revision 85914) +++ Doc/whatsnew/2.7.rst (working copy) @@ -177,7 +177,7 @@ The :class:`~collections.OrderedDict` API provides the same interface as regular dictionaries but iterates over keys and values in a guaranteed order -depending on when a key was first inserted:: +depending on when a key was first inserted: >>> from collections import OrderedDict >>> d = OrderedDict([('first', 1), @@ -187,13 +187,13 @@ [('first', 1), ('second', 2), ('third', 3)] If a new entry overwrites an existing entry, the original insertion -position is left unchanged:: +position is left unchanged: >>> d['second'] = 4 >>> d.items() [('first', 1), ('second', 4), ('third', 3)] -Deleting an entry and reinserting it will move it to the end:: +Deleting an entry and reinserting it will move it to the end: >>> del d['second'] >>> d['second'] = 5 @@ -203,7 +203,7 @@ The :meth:`~collections.OrderedDict.popitem` method has an optional *last* argument that defaults to True. If *last* is True, the most recently added key is returned and removed; if it's False, the -oldest key is selected:: +oldest key is selected: >>> od = OrderedDict([(x,0) for x in range(20)]) >>> od.popitem() @@ -216,7 +216,7 @@ (1, 0) Comparing two ordered dictionaries checks both the keys and values, -and requires that the insertion order was the same:: +and requires that the insertion order was the same: >>> od1 = OrderedDict([('first', 1), ... ('second', 2), @@ -281,7 +281,7 @@ Therefore, a simple comma-grouping mechanism has been added to the mini-language used by the :meth:`str.format` method. When formatting a floating-point number, simply include a comma between the -width and the precision:: +width and the precision: >>> '{:20,.2f}'.format(18446744073709551616.0) '18,446,744,073,709,551,616.00' @@ -572,14 +572,14 @@ >>> import string >>> m = memoryview(string.letters) >>> m - + >>> len(m) # Returns length of underlying object 52 >>> m[0], m[25], m[26] # Indexing returns one byte ('a', 'z', 'A') >>> m2 = m[0:26] # Slicing returns another memoryview >>> m2 - + The content of the view can be converted to a string of bytes or a list of integers: @@ -712,11 +712,11 @@ 65535L Python 2.7's floating-point result is larger, but much closer to the - true value:: + true value: >>> n = 295147905179352891391 >>> float(n) - 2.9514790517935289e+20 + 2.951479051793529e+20 >>> n - long(float(n)) -1L @@ -731,7 +731,7 @@ * The :meth:`str.format` method now supports automatic numbering of the replacement fields. This makes using :meth:`str.format` more closely resemble using - ``%s`` formatting:: + ``%s`` formatting: >>> '{}:{}:{}'.format(2009, 04, 'Sunday') '2009:4:Sunday' @@ -768,7 +768,7 @@ * The :func:`int` and :func:`long` types gained a ``bit_length`` method that returns the number of bits necessary to represent - its argument in binary:: + its argument in binary: >>> n = 37 >>> bin(n) @@ -1025,11 +1025,11 @@ :meth:`~collections.Counter.subtract` takes an iterable and subtracts one for each element instead of adding; if the argument is a dictionary or another :class:`Counter`, the counts are - subtracted. :: + subtracted. >>> c.most_common(5) [(' ', 6), ('e', 5), ('s', 3), ('a', 2), ('i', 2)] - >>> c.elements() -> + >>> c.elements() -> # doctest: +SKIP 'a', 'a', ' ', ' ', ' ', ' ', ' ', ' ', 'e', 'e', 'e', 'e', 'e', 'g', 'f', 'i', 'i', 'h', 'h', 'm', 'l', 'l', 'o', 'n', 'p', 's', @@ -1075,7 +1075,7 @@ * Constructors for the parsing classes in the :mod:`ConfigParser` module now take a *allow_no_value* parameter, defaulting to false; if true, - options without values will be allowed. For example:: + options without values will be allowed. For example: >>> import ConfigParser, StringIO >>> sample_config = """ @@ -1267,14 +1267,14 @@ * New function: the :mod:`inspect` module's :func:`~inspect.getcallargs` takes a callable and its positional and keyword arguments, and figures out which of the callable's parameters will receive each argument, - returning a dictionary mapping argument names to their values. For example:: + returning a dictionary mapping argument names to their values. For example: >>> from inspect import getcallargs >>> def f(a, b=1, *pos, **named): ... pass - >>> getcallargs(f, 1, 2, 3) + >>> getcallargs(f, 1, 2, 3) # doctest: +SKIP {'a': 1, 'b': 2, 'pos': (3,), 'named': {}} - >>> getcallargs(f, a=2, x=4) + >>> getcallargs(f, a=2, x=4) # doctest: +SKIP {'a': 2, 'b': 1, 'pos': (), 'named': {'x': 4}} >>> getcallargs(f) Traceback (most recent call last): @@ -1592,13 +1592,13 @@ ``://`` is treated as the scheme, even if it's a made-up scheme that the module doesn't know about. This change may break code that worked around the old behaviour. For example, Python 2.6.4 or 2.5 - will return the following: + will return the following:: >>> import urlparse >>> urlparse.urlsplit('invented://host/filename?query') ('invented', '', '//host/filename?query', '', '') - Python 2.7 (and Python 2.6.5) will return: + Python 2.7 (and Python 2.6.5) will return:: >>> import urlparse >>> urlparse.urlsplit('invented://host/filename?query') 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) @@ -64,6 +64,9 @@ Here's a sample session using the :class:`FTP_TLS` class: +.. doctest:: + :options: +SKIP + >>> from ftplib import FTP_TLS >>> ftps = FTP_TLS('ftp.python.org') >>> ftps.login() # login anonymously before securing control channel 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') @@ -1485,6 +1491,9 @@ :class:`FileType` objects as their type will open command-line args as files with the requested modes and buffer sizes: +.. doctest:: + :options: +SKIP + >>> parser = argparse.ArgumentParser() >>> parser.add_argument('--output', type=argparse.FileType('wb', 0)) >>> parser.parse_args(['--output', 'out']) @@ -1494,6 +1503,9 @@ convert this into ``sys.stdin`` for readable :class:`FileType` objects and ``sys.stdout`` for writable :class:`FileType` objects: +.. doctest:: + :options: +SKIP + >>> parser = argparse.ArgumentParser() >>> parser.add_argument('infile', type=argparse.FileType('r')) >>> parser.parse_args(['-']) 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