Merged revisions 59883-59920 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk

........
  r59887 | neal.norwitz | 2008-01-10 06:42:58 +0100 (Thu, 10 Jan 2008) | 1 line

  Reword entry, not sure I made it much better though.
........
  r59888 | andrew.kuchling | 2008-01-10 14:37:12 +0100 (Thu, 10 Jan 2008) | 1 line

  Check for fd of -1 to save fsync() and fstat() call
........
  r59891 | thomas.heller | 2008-01-10 19:45:40 +0100 (Thu, 10 Jan 2008) | 1 line

  Reflow a paragraph, and fix a typo.
........
  r59892 | raymond.hettinger | 2008-01-10 20:15:10 +0100 (Thu, 10 Jan 2008) | 1 line

  Examples for named tuple subclassing should include __slots__
........
  r59895 | raymond.hettinger | 2008-01-10 21:37:12 +0100 (Thu, 10 Jan 2008) | 1 line

  Clarify how to add a field to a named tuple.
........
  r59896 | amaury.forgeotdarc | 2008-01-10 22:59:42 +0100 (Thu, 10 Jan 2008) | 12 lines

  Closing issue1761.
  Surprising behaviour of the "$" regexp: it matches the
  end of the string, AND just before the newline at the end
  of the string::

      re.sub('$', '#', 'foo\n') == 'foo#\n#'

  Python is consistent with Perl and the pcre library, so
  we just document it.
  Guido prefers "\Z" to match only the end of the string.
........
  r59898 | raymond.hettinger | 2008-01-11 00:00:01 +0100 (Fri, 11 Jan 2008) | 1 line

  Neaten-up the named tuple docs
........
  r59900 | raymond.hettinger | 2008-01-11 01:23:13 +0100 (Fri, 11 Jan 2008) | 1 line

  Run doctests on the collections module
........
  r59903 | raymond.hettinger | 2008-01-11 02:25:54 +0100 (Fri, 11 Jan 2008) | 1 line

  Doctest results return a named tuple for readability
........
  r59904 | raymond.hettinger | 2008-01-11 03:12:33 +0100 (Fri, 11 Jan 2008) | 1 line

  Comment-out missing constant (from rev 59819)
........
  r59905 | raymond.hettinger | 2008-01-11 03:24:13 +0100 (Fri, 11 Jan 2008) | 1 line

  Have Decimal.as_tuple return a named tuple.
........
  r59906 | raymond.hettinger | 2008-01-11 04:04:50 +0100 (Fri, 11 Jan 2008) | 1 line

  Let most inspect functions return named tuples
........
  r59907 | raymond.hettinger | 2008-01-11 04:20:54 +0100 (Fri, 11 Jan 2008) | 1 line

  Improve usability of the SequenceMatcher by returning named tuples describing match ranges.
........
  r59909 | thomas.heller | 2008-01-11 09:04:03 +0100 (Fri, 11 Jan 2008) | 1 line

  Add an important missing blank.
........
  r59910 | georg.brandl | 2008-01-11 10:19:11 +0100 (Fri, 11 Jan 2008) | 2 lines

  Guard definition of TIPC_SUB_CANCEL with an #ifdef.
........
  r59911 | georg.brandl | 2008-01-11 10:20:58 +0100 (Fri, 11 Jan 2008) | 2 lines

  News entries for rev. 5990[567].
........
  r59912 | georg.brandl | 2008-01-11 10:55:53 +0100 (Fri, 11 Jan 2008) | 2 lines

  Documentation for r5990[3567].
........
  r59913 | thomas.heller | 2008-01-11 13:41:39 +0100 (Fri, 11 Jan 2008) | 4 lines

  The sqlite3 dll, when compiled in debug mode, must be linked with /MDd
  to use the debug runtime library.  Further, the dll will be named
  sqlite3_d.dll.
........
  r59919 | thomas.heller | 2008-01-11 16:38:46 +0100 (Fri, 11 Jan 2008) | 6 lines

  Revert revision 59913, because it was wrong:

    The sqlite3 dll, when compiled in debug mode, must be linked with
    /MDd to use the debug runtime library.  Further, the dll will be
    named sqlite3_d.dll.
........
  r59920 | christian.heimes | 2008-01-11 16:42:29 +0100 (Fri, 11 Jan 2008) | 1 line

  Removed unused variable
........
diff --git a/Doc/glossary.rst b/Doc/glossary.rst
index 6d12d0f..194fbd9 100644
--- a/Doc/glossary.rst
+++ b/Doc/glossary.rst
@@ -327,6 +327,13 @@
    mutable
       Mutable objects can change their value but keep their :func:`id`.  See
       also :term:`immutable`.
+
+   named tuple
+      A tuple subclass whose elements also are accessible as attributes via
+      fixed names (the class name and field names are indicated in the
+      individual documentation of a named tuple type, like ``TestResults(failed,
+      attempted)``).  Named tuple classes are created by
+      :func:`collections.namedtuple`.
     
    namespace
       The place where a variable is stored.  Namespaces are implemented as
diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst
index fdfdefe..f1a8fff 100644
--- a/Doc/library/collections.rst
+++ b/Doc/library/collections.rst
@@ -397,8 +397,8 @@
    method which lists the tuple contents in a ``name=value`` format.
 
    The *fieldnames* are a single string with each fieldname separated by whitespace
-   and/or commas (for example 'x y' or 'x, y').  Alternatively, *fieldnames*
-   can be a sequence of strings (such as ['x', 'y']).
+   and/or commas, for example ``'x y'`` or ``'x, y'``.  Alternatively, *fieldnames*
+   can be a sequence of strings such as ``['x', 'y']``.
 
    Any valid Python identifier may be used for a fieldname except for names
    starting with an underscore.  Valid identifiers consist of letters, digits,
@@ -406,7 +406,7 @@
    a :mod:`keyword` such as *class*, *for*, *return*, *global*, *pass*, *print*,
    or *raise*.
 
-   If *verbose* is true, will print the class definition.
+   If *verbose* is true, the class definition is printed just before being built.
 
    Named tuple instances do not have per-instance dictionaries, so they are
    lightweight and require no more memory than regular tuples.
@@ -533,7 +533,7 @@
     >>> getattr(p, 'x')
     11
 
-To cast a dictionary to a named tuple, use the double-star-operator [#]_::
+To convert a dictionary to a named tuple, use the double-star-operator [#]_::
 
    >>> d = {'x': 11, 'y': 22}
    >>> Point(**d)
@@ -544,23 +544,24 @@
 a fixed-width print format::
 
     >>> 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)
 
-    Point: x= 3.000 y= 4.000 hypot= 5.000
-    Point: x=14.000 y= 5.000 hypot=14.866
-    Point: x= 1.286 y= 6.000 hypot= 6.136
+    Point: x= 3.000  y= 4.000  hypot= 5.000
+    Point: x=14.000  y= 0.714  hypot=14.018
 
 Another use for subclassing is to replace performance critcal methods with
-faster versions that bypass error-checking and that localize variable access::
+faster versions that bypass error-checking::
 
     class Point(namedtuple('Point', 'x y')):
+        __slots__ = ()
         _make = classmethod(tuple.__new__)
         def _replace(self, _map=map, **kwds):
             return self._make(_map(kwds.get, ('x', 'y'), self))
@@ -569,7 +570,7 @@
 Subclassing is not useful for adding new, stored fields.  Instead, simply
 create a new named tuple type from the :attr:`_fields` attribute::
 
-    >>> Pixel = namedtuple('Pixel', Point._fields + Color._fields)
+    >>> Point3D = namedtuple('Point3D', Point._fields + ('z',))
 
 Default values can be implemented by using :meth:`_replace` to
 customize a prototype instance::
diff --git a/Doc/library/decimal.rst b/Doc/library/decimal.rst
index e29e4ea..fbd6f43 100644
--- a/Doc/library/decimal.rst
+++ b/Doc/library/decimal.rst
@@ -328,7 +328,11 @@
 
 .. method:: Decimal.as_tuple()
 
-   Return a tuple representation of the number: ``(sign, digit_tuple, exponent)``.
+   Return a :term:`named tuple` representation of the number:
+   ``DecimalTuple(sign, digits, exponent)``.
+
+   .. versionchanged:: 2.6
+      Use a named tuple.
 
 
 .. method:: Decimal.canonical()
diff --git a/Doc/library/difflib.rst b/Doc/library/difflib.rst
index 34dbcfd..7e61aa9 100644
--- a/Doc/library/difflib.rst
+++ b/Doc/library/difflib.rst
@@ -336,7 +336,7 @@
 
    Find longest matching block in ``a[alo:ahi]`` and ``b[blo:bhi]``.
 
-   If *isjunk* was omitted or ``None``, :meth:`get_longest_match` returns ``(i, j,
+   If *isjunk* was omitted or ``None``, :meth:`find_longest_match` returns ``(i, j,
    k)`` such that ``a[i:i+k]`` is equal to ``b[j:j+k]``, where ``alo <= i <= i+k <=
    ahi`` and ``blo <= j <= j+k <= bhi``. For all ``(i', j', k')`` meeting those
    conditions, the additional conditions ``k >= k'``, ``i <= i'``, and if ``i ==
@@ -365,6 +365,9 @@
 
    If no blocks match, this returns ``(alo, blo, 0)``.
 
+   .. versionchanged:: 2.6
+      This method returns a :term:`named tuple` ``Match(a, b, size)``.
+
 
 .. method:: SequenceMatcher.get_matching_blocks()
 
diff --git a/Doc/library/doctest.rst b/Doc/library/doctest.rst
index 04bc219..ce8b9f0 100644
--- a/Doc/library/doctest.rst
+++ b/Doc/library/doctest.rst
@@ -1436,11 +1436,14 @@
 .. method:: DocTestRunner.summarize([verbose])
 
    Print a summary of all the test cases that have been run by this DocTestRunner,
-   and return a tuple ``(failure_count, test_count)``.
+   and return a :term:`named tuple` ``TestResults(failed, attempted)``.
 
    The optional *verbose* argument controls how detailed the summary is.  If the
    verbosity is not specified, then the :class:`DocTestRunner`'s verbosity is used.
 
+   .. versionchanged:: 2.6
+      Use a named tuple.
+
 
 .. _doctest-outputchecker:
 
diff --git a/Doc/library/inspect.rst b/Doc/library/inspect.rst
index e5008f6..5daa496 100644
--- a/Doc/library/inspect.rst
+++ b/Doc/library/inspect.rst
@@ -188,7 +188,8 @@
 
 .. function:: getmoduleinfo(path)
 
-   Return a tuple of values that describe how Python will interpret the file
+   Returns a :term:`named tuple` ``ModuleInfo(name, suffix, mode,
+   module_type)`` of values that describe how Python will interpret the file
    identified by *path* if it is a module, or ``None`` if it would not be
    identified as a module.  The return tuple is ``(name, suffix, mode, mtype)``,
    where *name* is the name of the module without the name of any enclosing
@@ -377,8 +378,9 @@
 
 .. function:: getargspec(func)
 
-   Get the names and default values of a function's arguments. A tuple of four
-   things is returned: ``(args, varargs, varkw, defaults)``. *args* is a list of
+   Get the names and default values of a function's arguments. A 
+   :term:`named tuple` ``ArgSpec(args, varargs, keywords,
+   defaults)`` is returned. *args* is a list of
    the argument names. *varargs* and *varkw* are the names of the ``*`` and
    ``**`` arguments or ``None``. *defaults* is a tuple of default argument
    values or None if there are no default arguments; if this tuple has *n*
@@ -391,10 +393,10 @@
 
 .. function:: getfullargspec(func)
 
-   Get the names and default values of a function's arguments.  A tuple of seven
-   things is returned:
+   Get the names and default values of a function's arguments.  A :term:`named tuple`
+   is returned:
 
-   ``(args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations)``
+   ``FullArgSpec(args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations)``
 
    *args* is a list of the argument names.  *varargs* and *varkw* are the names
    of the ``*`` and ``**`` arguments or ``None``.  *defaults* is an n-tuple of
@@ -408,8 +410,8 @@
 
 .. function:: getargvalues(frame)
 
-   Get information about arguments passed into a particular frame. A tuple of four
-   things is returned: ``(args, varargs, varkw, locals)``. *args* is a list of the
+   Get information about arguments passed into a particular frame. A :term:`named tuple` 
+   ``ArgInfo(args, varargs, keywords, locals)`` is returned. *args* is a list of the
    argument names (it may contain nested lists). *varargs* and *varkw* are the
    names of the ``*`` and ``**`` arguments or ``None``. *locals* is the locals
    dictionary of the given frame.
@@ -476,8 +478,8 @@
 
 .. function:: getframeinfo(frame[, context])
 
-   Get information about a frame or traceback object.  A 5-tuple is returned, the
-   last five elements of the frame's frame record.
+   Get information about a frame or traceback object.  A :term:`named tuple` 
+   ``Traceback(filename, lineno, function, code_context, index)`` is returned.
 
 
 .. function:: getouterframes(frame[, context])
diff --git a/Doc/library/re.rst b/Doc/library/re.rst
index 49c5215..7de088a 100644
--- a/Doc/library/re.rst
+++ b/Doc/library/re.rst
@@ -98,7 +98,9 @@
    string, and in :const:`MULTILINE` mode also matches before a newline.  ``foo``
    matches both 'foo' and 'foobar', while the regular expression ``foo$`` matches
    only 'foo'.  More interestingly, searching for ``foo.$`` in ``'foo1\nfoo2\n'``
-   matches 'foo2' normally, but 'foo1' in :const:`MULTILINE` mode.
+   matches 'foo2' normally, but 'foo1' in :const:`MULTILINE` mode; searching for
+   a single ``$`` in ``'foo\n'`` will find two (empty) matches: one just before
+   the newline, and one at the end of the string.
 
 ``'*'``
    Causes the resulting RE to match 0 or more repetitions of the preceding RE, as
diff --git a/Lib/collections.py b/Lib/collections.py
index e1e9d11..78f92ce 100644
--- a/Lib/collections.py
+++ b/Lib/collections.py
@@ -117,23 +117,28 @@
 
     # 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 1f5ff12..434930a 100644
--- a/Lib/decimal.py
+++ b/Lib/decimal.py
@@ -137,6 +137,12 @@
 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 @@
 
         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 82e3319..361be6e 100644
--- a/Lib/difflib.py
+++ b/Lib/difflib.py
@@ -30,9 +30,12 @@
 
 __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 @@
 
         >>> 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 @@
 
         >>> 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 @@
               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 @@
         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 @@
 
         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 4a2da32..b5fa574 100644
--- a/Lib/doctest.py
+++ b/Lib/doctest.py
@@ -99,6 +99,9 @@
 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 @@
         >>> 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 @@
         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 @@
 
         # 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 @@
             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 @@
          ...      ''', {}, 'foo', 'foo.py', 0)
 
          >>> runner.run(test)
-         (0, 1)
+         TestResults(failed=0, attempted=1)
 
          >>> test.globs
          {}
@@ -1818,7 +1821,7 @@
     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 @@
     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 @@
         (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 @@
         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 c0db4bc..074754f 100644
--- a/Lib/inspect.py
+++ b/Lib/inspect.py
@@ -31,6 +31,7 @@
 
 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 @@
     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 @@
         else:
             kind = "data"
 
-        result.append((name, kind, homecls, obj))
+        result.append(Attribute(name, kind, homecls, obj))
 
     return result
 
@@ -362,6 +365,8 @@
     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 @@
     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 @@
 # 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 @@
     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 @@
         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 @@
     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 @@
     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 @@
     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 @@
     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 d8cf72e..77af0fb 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 @@
             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 db370b1..07e2542 100644
--- a/Lib/test/test_doctest.py
+++ b/Lib/test/test_doctest.py
@@ -658,7 +658,7 @@
 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 @@
     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 @@
     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 @@
     >>> # 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 @@
     Expecting:
         6
     ok
-    (0, 3)
+    TestResults(failed=0, attempted=3)
 
     >>> # Restore sys.argv
     >>> sys.argv = old_argv
@@ -780,7 +780,7 @@
     ...     '''
     >>> 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 @@
     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 @@
     ...     '''
     >>> 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 @@
         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 @@
     ...     '''
     >>> 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 @@
         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 @@
         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 @@
     >>> # 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 @@
         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 @@
     >>> # 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 @@
         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 @@
          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 @@
         [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 @@
         e
         f
         g
-    (1, 1)
+    TestResults(failed=1, attempted=1)
 
     >>> # With the flag:
     >>> test = doctest.DocTestFinder().find(f)[0]
@@ -1131,7 +1131,7 @@
          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 @@
         + 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 @@
         ?                       ^
         + 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 @@
         200
     Got:
         2
-    (3, 5)
+    TestResults(failed=3, attempted=5)
 
 However, output from `report_start` is not supressed:
 
@@ -1241,7 +1241,7 @@
         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 @@
     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 @@
         [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 @@
         [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 @@
         [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 @@
         [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 @@
         [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 @@
         [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 @@
     ...     '''
     >>> 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 @@
     ...     '''
     >>> 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 @@
     ...     '''
     >>> 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 @@
       (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 @@
       (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 @@
       Expected nothing
       Got:
           9
-      (1, 3)
+      TestResults(failed=1, attempted=3)
       """
 
 def test_pdb_set_trace_nested():
@@ -1795,7 +1795,7 @@
     (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 @@
     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 @@
 
     >>> 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 @@
     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 @@
 
     >>> 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 @@
     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 @@
     **********************************************************************
     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 @@
     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 @@
     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 @@
     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 @@
 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 @@
             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 @@
         ...     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 @@
         >>> 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 b88cb7e..5d46db1 100644
--- a/Lib/test/test_pyclbr.py
+++ b/Lib/test/test_pyclbr.py
@@ -40,7 +40,7 @@
         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 @@
 
     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 866f598..28e508c 100644
--- a/Lib/test/test_re.py
+++ b/Lib/test/test_re.py
@@ -661,6 +661,18 @@
         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
diff --git a/Modules/mmapmodule.c b/Modules/mmapmodule.c
index 84f909e..8302767 100644
--- a/Modules/mmapmodule.c
+++ b/Modules/mmapmodule.c
@@ -980,9 +980,11 @@
 #ifdef HAVE_FSTAT
 #  ifdef __VMS
 	/* on OpenVMS we must ensure that all bytes are written to the file */
-	fsync(fd);
+	if (fd != -1) {
+	        fsync(fd);
+	}
 #  endif
-	if (fstat(fd, &st) == 0 && S_ISREG(st.st_mode)) {
+	if (fd != -1 && fstat(fd, &st) == 0 && S_ISREG(st.st_mode)) {
 		if (map_size == 0) {
 			map_size = st.st_size;
 		} else if ((size_t)offset + (size_t)map_size > st.st_size) {
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c
index dc05108..7ad96d3 100644
--- a/Modules/socketmodule.c
+++ b/Modules/socketmodule.c
@@ -4097,7 +4097,7 @@
 PyMODINIT_FUNC
 init_socket(void)
 {
-	PyObject *m, *has_ipv6, *tmp;
+	PyObject *m, *has_ipv6;
 
 	if (!os_init())
 		return;
@@ -4354,7 +4354,10 @@
 	/* for subscriptions */
 	PyModule_AddIntConstant(m, "TIPC_SUB_PORTS", TIPC_SUB_PORTS);
 	PyModule_AddIntConstant(m, "TIPC_SUB_SERVICE", TIPC_SUB_SERVICE);
+#ifdef TIPC_SUB_CANCEL
+	/* doesn't seem to be available everywhere */
 	PyModule_AddIntConstant(m, "TIPC_SUB_CANCEL", TIPC_SUB_CANCEL);
+#endif
 	PyModule_AddIntConstant(m, "TIPC_WAIT_FOREVER", TIPC_WAIT_FOREVER);
 	PyModule_AddIntConstant(m, "TIPC_PUBLISHED", TIPC_PUBLISHED);
 	PyModule_AddIntConstant(m, "TIPC_WITHDRAWN", TIPC_WITHDRAWN);
diff --git a/PCbuild/build_tkinter.py b/PCbuild/build_tkinter.py
index a7205d0..574d768 100644
--- a/PCbuild/build_tkinter.py
+++ b/PCbuild/build_tkinter.py
@@ -25,7 +25,7 @@
 # Windows 2000 compatibility: WINVER 0x0500
 # http://msdn2.microsoft.com/en-us/library/aa383745.aspx
 NMAKE = ('nmake /nologo /f %s '
-    'COMPILERFLAGS=\"-DWINVER=0x0500 -D_WIN32_WINNT=0x0500 -DNTDDI_VERSION=NTDDI_WIN2KSP4\"'
+    'COMPILERFLAGS=\"-DWINVER=0x0500 -D_WIN32_WINNT=0x0500 -DNTDDI_VERSION=NTDDI_WIN2KSP4\" '
     '%s %s')
 
 def nmake(makefile, command="", **kw):
diff --git a/PCbuild/readme.txt b/PCbuild/readme.txt
index 00b7de0..764ab8a 100644
--- a/PCbuild/readme.txt
+++ b/PCbuild/readme.txt
@@ -117,7 +117,7 @@
     Build with build_tkinter.py
     ---------------------------
     The PCbuild directory contains a Python script which automates all
-    steps. Run the script in a Visual Studio 2009 command prompt with 
+    steps. Run the script in a Visual Studio 2008 command prompt with 
 
       python build_tkinter.py Win32
 
@@ -312,9 +312,11 @@
 Profile Guided Optimization
 ---------------------------
 
-The solution has two configurations for PGO. The PGInstrument configuration
-must be build first. The PGInstrument binaries are lniked against a profiling
-library and contain extra debug information. The PGUpdate configuration takes the profiling data and generates optimized binaries.
+The solution has two configurations for PGO. The PGInstrument
+configuration must be build first. The PGInstrument binaries are
+lniked against a profiling library and contain extra debug
+information. The PGUpdate configuration takes the profiling data and
+generates optimized binaries.
 
 The build_pgo.bat script automates the creation of optimized binaries. It
 creates the PGI files, runs the unit test suite or PyBench with the PGI