[Python-checkins] r69031 - in python/branches/py3k-issue1717: Doc/distutils/apiref.rst Doc/library/collections.rst Doc/library/importlib.rst Doc/library/itertools.rst Doc/library/operator.rst Lib/collections.py Lib/ctypes/test/test_libc.py Lib/distutils/ccompiler.py Lib/distutils/command/sdist.py Lib/distutils/mwerkscompiler.py Lib/distutils/tests/test_sdist.py Lib/doctest.py Lib/idlelib/PyShell.py Lib/importlib/NOTES Lib/importlib/test/builtin/test_finder.py Lib/importlib/test/extension/test_finder.py Lib/importlib/test/finder_tests.py Lib/importlib/test/frozen/test_finder.py Lib/importlib/test/loader_tests.py Lib/locale.py Lib/test/test_array.py Lib/test/test_bool.py Lib/test/test_cmd_line.py Lib/test/test_contains.py Lib/test/test_copy.py Lib/test/test_datetime.py Lib/test/test_itertools.py Lib/test/test_operator.py Lib/test/test_sundry.py Lib/test/test_uuid.py Lib/unittest.py Lib/xml/dom/minidom.py Lib/xml/etree/ElementTree.py Misc/NEWS Modules/_ssl.c Modules/itertoolsmodule.c Modules/operator.c Objects/longobject.c Python/makeopcodetargets.py Python/pythonrun.c

mark.dickinson python-checkins at python.org
Tue Jan 27 21:24:53 CET 2009


Author: mark.dickinson
Date: Tue Jan 27 21:24:52 2009
New Revision: 69031

Log:
Merged revisions 68928,68931,68935,68937,68949,68954,68956-68957,68960-68961,68963,68965,68969,68977,68980-68981,68986,68991-68993,68995-68997,68999-69000,69002,69004-69005,69007,69011,69013,69015,69019-69020,69022,69024-69025 via svnmerge from 
svn+ssh://pythondev@svn.python.org/python/branches/py3k

................
  r68928 | hirokazu.yamamoto | 2009-01-25 17:50:07 +0000 (Sun, 25 Jan 2009) | 8 lines
  
  Blocked revisions 68927 via svnmerge
  
  ........
    r68927 | hirokazu.yamamoto | 2009-01-26 02:46:48 +0900 | 1 line
    
    Fixed compile error on windows.
  ........
................
  r68931 | tarek.ziade | 2009-01-25 18:27:45 +0000 (Sun, 25 Jan 2009) | 9 lines
  
  Merged revisions 68929 via svnmerge from 
  svn+ssh://pythondev@svn.python.org/python/trunk
  
  ........
    r68929 | tarek.ziade | 2009-01-25 19:19:25 +0100 (Sun, 25 Jan 2009) | 1 line
    
    Fixed #4863: removed distutils.mwerkscompiler
  ........
................
  r68935 | tarek.ziade | 2009-01-25 19:31:22 +0000 (Sun, 25 Jan 2009) | 9 lines
  
  Merged revisions 68933 via svnmerge from 
  svn+ssh://pythondev@svn.python.org/python/trunk
  
  ........
    r68933 | tarek.ziade | 2009-01-25 20:29:10 +0100 (Sun, 25 Jan 2009) | 1 line
    
    Issue #4863, removing remaining bits
  ........
................
  r68937 | benjamin.peterson | 2009-01-25 19:44:16 +0000 (Sun, 25 Jan 2009) | 1 line
  
  use the classmethod directive
................
  r68949 | mark.dickinson | 2009-01-25 22:25:06 +0000 (Sun, 25 Jan 2009) | 10 lines
  
  Merged revisions 68947 via svnmerge from 
  svn+ssh://pythondev@svn.python.org/python/trunk
  
  ........
    r68947 | mark.dickinson | 2009-01-25 22:12:31 +0000 (Sun, 25 Jan 2009) | 3 lines
    
    No need for carry to be type twodigits in _PyLong_AsByteArray; digit is large enough.
    This change should silence a compiler warning on Windows.
  ........
................
  r68954 | brett.cannon | 2009-01-26 01:21:47 +0000 (Mon, 26 Jan 2009) | 9 lines
  
  Blocked revisions 68953 via svnmerge
  
  ........
    r68953 | brett.cannon | 2009-01-25 17:16:50 -0800 (Sun, 25 Jan 2009) | 3 lines
    
    Backport importlib in the form of providing importlib.import_module(). This has
    been done purely to help transitions from 2.7 to 3.1.
  ........
................
  r68956 | brett.cannon | 2009-01-26 01:54:40 +0000 (Mon, 26 Jan 2009) | 1 line
  
  Update NOTES for importlib.
................
  r68957 | raymond.hettinger | 2009-01-26 02:09:03 +0000 (Mon, 26 Jan 2009) | 9 lines
  
  As discussed on python-dev, remove several operator functions
  isSequenceType(), isMappingType(), and isNumberType() in favor
  of using abstract base classes.  Also, remove repeat() and irepeat()
  in favor of mul() and imul().
  
  After the buildbots have had a go at this.  Will backport to Py3.0.1.
  For Py2.7, will just mark as deprecated.
................
  r68960 | raymond.hettinger | 2009-01-26 02:23:50 +0000 (Mon, 26 Jan 2009) | 1 line
  
  Backport r68942:  update powerset() recipe.
................
  r68961 | raymond.hettinger | 2009-01-26 02:56:58 +0000 (Mon, 26 Jan 2009) | 1 line
  
  Forward port r68941 adding itertools.compress().
................
  r68963 | benjamin.peterson | 2009-01-26 03:50:45 +0000 (Mon, 26 Jan 2009) | 12 lines
  
  Blocked revisions 68941-68942 via svnmerge
  
  ........
    r68941 | raymond.hettinger | 2009-01-25 15:04:14 -0600 (Sun, 25 Jan 2009) | 1 line
    
    Promote compress() from a recipe to being a regular itertool.
  ........
    r68942 | raymond.hettinger | 2009-01-25 15:31:47 -0600 (Sun, 25 Jan 2009) | 1 line
    
    Improved itertools recipe for generating powerset().
  ........
................
  r68965 | raymond.hettinger | 2009-01-26 16:53:29 +0000 (Mon, 26 Jan 2009) | 1 line
  
  Fix signed/unsigned mismatch.
................
  r68969 | tarek.ziade | 2009-01-26 17:23:20 +0000 (Mon, 26 Jan 2009) | 9 lines
  
  Merged revisions 68951 via svnmerge from 
  svn+ssh://pythondev@svn.python.org/python/trunk
  
  ........
    r68951 | tarek.ziade | 2009-01-26 00:34:00 +0100 (Mon, 26 Jan 2009) | 1 line
    
    Fixed #1885: --formats=tar,gztar was not working properly in the sdist command
  ........
................
  r68977 | antoine.pitrou | 2009-01-26 21:48:00 +0000 (Mon, 26 Jan 2009) | 3 lines
  
  Followup of #4705: we can't skip the binary buffering layer for stdin because FileIO doesn't have a read1() method
................
  r68980 | mark.dickinson | 2009-01-26 21:56:07 +0000 (Mon, 26 Jan 2009) | 14 lines
  
  Merged revisions 68974-68975 via svnmerge from 
  svn+ssh://pythondev@svn.python.org/python/trunk
  
  ........
    r68974 | mark.dickinson | 2009-01-26 21:36:30 +0000 (Mon, 26 Jan 2009) | 4 lines
    
    Fix undefined behaviour (left shift of negative value) in long_hash.  Also,
    rewrap a line of length > 79, and update comments.
  ........
    r68975 | mark.dickinson | 2009-01-26 21:40:08 +0000 (Mon, 26 Jan 2009) | 2 lines
    
    Fix comment.
  ........
................
  r68981 | antoine.pitrou | 2009-01-26 22:00:21 +0000 (Mon, 26 Jan 2009) | 3 lines
  
  Fix test so as to also pass in debug mode
................
  r68986 | raymond.hettinger | 2009-01-27 00:28:36 +0000 (Tue, 27 Jan 2009) | 1 line
  
  Forward port r68985: Idle startup message.
................
  r68991 | brett.cannon | 2009-01-27 01:33:54 +0000 (Tue, 27 Jan 2009) | 2 lines
  
  Move importlib.test.extension.test_finder over to importlib.test.finder_tests.
................
  r68992 | brett.cannon | 2009-01-27 01:34:30 +0000 (Tue, 27 Jan 2009) | 2 lines
  
  Make importlib.test.finder_tests an ABC.
................
  r68993 | brett.cannon | 2009-01-27 01:41:57 +0000 (Tue, 27 Jan 2009) | 2 lines
  
  Move importlib.test.builtin.test_finder over to importlib.test.finder_tests.
................
  r68995 | brett.cannon | 2009-01-27 01:44:50 +0000 (Tue, 27 Jan 2009) | 2 lines
  
  Move importlib.test.frozen.test_finder over to importlib.test.finder_tests.
................
  r68996 | brett.cannon | 2009-01-27 01:46:04 +0000 (Tue, 27 Jan 2009) | 1 line
  
  Update importlib NOTES.
................
  r68997 | benjamin.peterson | 2009-01-27 02:30:47 +0000 (Tue, 27 Jan 2009) | 15 lines
  
  Blocked revisions 68964,68985 via svnmerge
  
  ........
    r68964 | raymond.hettinger | 2009-01-26 10:52:22 -0600 (Mon, 26 Jan 2009) | 1 line
    
    Fix signed/unsigned mismatch.
  ........
    r68985 | raymond.hettinger | 2009-01-26 17:29:09 -0600 (Mon, 26 Jan 2009) | 6 lines
    
    Remove startup firewall message.  That is handled by an error dialog
    whenever a connection cannot be formed.  Also, the Idle version number
    is already in the About Idle dialog.  Now, the startup is clean looking
    once again.
  ........
................
  r68999 | raymond.hettinger | 2009-01-27 02:38:22 +0000 (Tue, 27 Jan 2009) | 3 lines
  
  Tweak column alignment in collections docs.
................
  r69000 | brett.cannon | 2009-01-27 02:39:33 +0000 (Tue, 27 Jan 2009) | 2 lines
  
  Initial take on importlib.test.loader_tests.
................
  r69002 | benjamin.peterson | 2009-01-27 03:02:38 +0000 (Tue, 27 Jan 2009) | 8 lines
  
  Blocked revisions 68998 via svnmerge
  
  ........
    r68998 | raymond.hettinger | 2009-01-26 20:36:33 -0600 (Mon, 26 Jan 2009) | 3 lines
    
    Tweak column alignment for collections docs.
  ........
................
  r69004 | raymond.hettinger | 2009-01-27 04:20:44 +0000 (Tue, 27 Jan 2009) | 1 line
  
  Forward port r69001: itertools.combinations_with_replacement().
................
  r69005 | raymond.hettinger | 2009-01-27 04:42:48 +0000 (Tue, 27 Jan 2009) | 1 line
  
  Put functions back in alphabetical order.
................
  r69007 | raymond.hettinger | 2009-01-27 04:57:51 +0000 (Tue, 27 Jan 2009) | 1 line
  
  Beautify grouper() recipe in docs.
................
  r69011 | raymond.hettinger | 2009-01-27 09:35:21 +0000 (Tue, 27 Jan 2009) | 1 line
  
  Add tests to verify combinatoric relationships.
................
  r69013 | raymond.hettinger | 2009-01-27 09:56:30 +0000 (Tue, 27 Jan 2009) | 1 line
  
  Stronger tests for combinatoric relationships.
................
  r69015 | raymond.hettinger | 2009-01-27 10:06:09 +0000 (Tue, 27 Jan 2009) | 1 line
  
  Issue 5021: doctest.testfile should set __name__
................
  r69019 | raymond.hettinger | 2009-01-27 10:39:42 +0000 (Tue, 27 Jan 2009) | 1 line
  
  More exhaustive combinatoric checks.
................
  r69020 | antoine.pitrou | 2009-01-27 10:49:58 +0000 (Tue, 27 Jan 2009) | 3 lines
  
  Add executable property to Python/makeopcodetargets.py
................
  r69022 | raymond.hettinger | 2009-01-27 11:06:40 +0000 (Tue, 27 Jan 2009) | 1 line
  
  Resurrect two buffer tests, converting irepeat() to imul().  Undoes part of r68962.
................
  r69024 | raymond.hettinger | 2009-01-27 13:29:43 +0000 (Tue, 27 Jan 2009) | 1 line
  
  Add more tests for the powerset() recipe.
................
  r69025 | mark.dickinson | 2009-01-27 18:17:45 +0000 (Tue, 27 Jan 2009) | 3 lines
  
  Issue #1717: Remove cmp.  Stage 1: remove all uses of cmp and __cmp__ from
  the standard library and tests.
................


Added:
   python/branches/py3k-issue1717/Lib/importlib/test/loader_tests.py
      - copied unchanged from r69025, /python/branches/py3k/Lib/importlib/test/loader_tests.py
Removed:
   python/branches/py3k-issue1717/Lib/distutils/mwerkscompiler.py
Modified:
   python/branches/py3k-issue1717/   (props changed)
   python/branches/py3k-issue1717/Doc/distutils/apiref.rst
   python/branches/py3k-issue1717/Doc/library/collections.rst
   python/branches/py3k-issue1717/Doc/library/importlib.rst
   python/branches/py3k-issue1717/Doc/library/itertools.rst
   python/branches/py3k-issue1717/Doc/library/operator.rst
   python/branches/py3k-issue1717/Lib/collections.py
   python/branches/py3k-issue1717/Lib/ctypes/test/test_libc.py
   python/branches/py3k-issue1717/Lib/distutils/ccompiler.py
   python/branches/py3k-issue1717/Lib/distutils/command/sdist.py
   python/branches/py3k-issue1717/Lib/distutils/tests/test_sdist.py
   python/branches/py3k-issue1717/Lib/doctest.py
   python/branches/py3k-issue1717/Lib/idlelib/PyShell.py
   python/branches/py3k-issue1717/Lib/importlib/NOTES
   python/branches/py3k-issue1717/Lib/importlib/test/builtin/test_finder.py
   python/branches/py3k-issue1717/Lib/importlib/test/extension/test_finder.py
   python/branches/py3k-issue1717/Lib/importlib/test/finder_tests.py
   python/branches/py3k-issue1717/Lib/importlib/test/frozen/test_finder.py
   python/branches/py3k-issue1717/Lib/locale.py
   python/branches/py3k-issue1717/Lib/test/test_array.py
   python/branches/py3k-issue1717/Lib/test/test_bool.py
   python/branches/py3k-issue1717/Lib/test/test_cmd_line.py
   python/branches/py3k-issue1717/Lib/test/test_contains.py
   python/branches/py3k-issue1717/Lib/test/test_copy.py
   python/branches/py3k-issue1717/Lib/test/test_datetime.py
   python/branches/py3k-issue1717/Lib/test/test_itertools.py
   python/branches/py3k-issue1717/Lib/test/test_operator.py
   python/branches/py3k-issue1717/Lib/test/test_sundry.py
   python/branches/py3k-issue1717/Lib/test/test_uuid.py
   python/branches/py3k-issue1717/Lib/unittest.py
   python/branches/py3k-issue1717/Lib/xml/dom/minidom.py
   python/branches/py3k-issue1717/Lib/xml/etree/ElementTree.py
   python/branches/py3k-issue1717/Misc/NEWS
   python/branches/py3k-issue1717/Modules/_ssl.c
   python/branches/py3k-issue1717/Modules/itertoolsmodule.c
   python/branches/py3k-issue1717/Modules/operator.c
   python/branches/py3k-issue1717/Objects/longobject.c
   python/branches/py3k-issue1717/Python/makeopcodetargets.py   (props changed)
   python/branches/py3k-issue1717/Python/pythonrun.c

Modified: python/branches/py3k-issue1717/Doc/distutils/apiref.rst
==============================================================================
--- python/branches/py3k-issue1717/Doc/distutils/apiref.rst	(original)
+++ python/branches/py3k-issue1717/Doc/distutils/apiref.rst	Tue Jan 27 21:24:52 2009
@@ -847,23 +847,6 @@
 :class:`UnixCCompiler` that handles the EMX port of the GNU C compiler to OS/2.
 
 
-:mod:`distutils.mwerkscompiler` --- Metrowerks CodeWarrior support
-==================================================================
-
-.. module:: distutils.mwerkscompiler
-   :synopsis: Metrowerks CodeWarrior support
-
-
-Contains :class:`MWerksCompiler`, an implementation of the abstract
-:class:`CCompiler` class for MetroWerks CodeWarrior on the pre-Mac OS X
-Macintosh. Needs work to support CW on Windows or Mac OS X.
-
-.. % \subsection{Utility modules}
-.. %
-.. % The following modules all provide general utility functions. They haven't
-.. % all been documented yet.
-
-
 :mod:`distutils.archive_util` ---  Archiving utilities
 ======================================================
 

Modified: python/branches/py3k-issue1717/Doc/library/collections.rst
==============================================================================
--- python/branches/py3k-issue1717/Doc/library/collections.rst	(original)
+++ python/branches/py3k-issue1717/Doc/library/collections.rst	Tue Jan 27 21:24:52 2009
@@ -171,10 +171,10 @@
    Elements are counted from an *iterable* or initialized from another
    *mapping* (or counter)::
 
-       >>> c = Counter()                            # a new, empty counter
-       >>> c = Counter('gallahad')                  # a new counter from an iterable
-       >>> c = Counter({'red': 4, 'blue': 2})       # a new counter from a mapping
-       >>> c = Counter(spam=8, eggs=1)              # a new counter from keyword args
+        >>> c = Counter()                           # a new, empty counter
+        >>> c = Counter('gallahad')                 # a new counter from an iterable
+        >>> c = Counter({'red': 4, 'blue': 2})      # a new counter from a mapping
+        >>> c = Counter(cats=4, dogs=8)             # a new counter from keyword args
 
    Counter objects have a dictionary interface except that they return a zero
    count for missing items instead of raising a :exc:`KeyError`::
@@ -207,10 +207,10 @@
 
    .. method:: most_common([n])
 
-      Return a list of the *n* most common elements and their counts from
-      the most common to the least.  If *n* is not specified or is ``None``,
-      return a list of all element counts in decreasing order of frequency.
-      Elements with equal counts are ordered arbitrarily::
+      Return a list of the *n* most common elements and their counts from the
+      most common to the least.  If *n* not specified, :func:`most_common`
+      returns *all* elements in the counter.  Elements with equal counts are
+      ordered arbitrarily::
 
             >>> Counter('abracadabra').most_common(3)
             [('a', 5), ('r', 2), ('b', 2)]
@@ -220,33 +220,26 @@
 
    .. method:: fromkeys(iterable)
 
-       This class method is not implemented for :class:`Counter` objects.
+      This class method is not implemented for :class:`Counter` objects.
 
    .. method:: update([iterable-or-mapping])
 
-       Elements are counted from an *iterable* or added-in from another
-       *mapping* (or counter).  Like :meth:`dict.update` but adds-in counts
-       instead of replacing them.  Also, the *iterable* is expected to be a
-       sequence of elements, not a sequence of ``(key, value)`` pairs::
-
-            >>> c = Counter('which')
-            >>> c.update('witch')           # add elements from another iterable
-            >>> d = Counter('watch')
-            >>> c.update(d)                 # add elements from another counter
-            >>> c['h']                      # four 'h' in which, witch, and watch
-            4
+      Elements are counted from an *iterable* or added-in from another
+      *mapping* (or counter).  Like :meth:`dict.update` but adds counts
+      instead of replacing them.  Also, the *iterable* is expected to be a
+      sequence of elements, not a sequence of ``(key, value)`` pairs.
 
 Common patterns for working with :class:`Counter` objects::
 
-    sum(c.values())               # total of all counts
-    c.clear()                     # reset all counts
-    list(c)                       # list unique elements
-    set(c)                        # convert to a set
-    dict(c)                       # convert to a regular dictionary
-    c.items()                     # convert to a list of (elem, cnt) pairs
-    Counter(dict(list_of_pairs))  # convert from a list of (elem, cnt) pairs
-    c.most_common()[:-n:-1]       # n least common elements
-    c += Counter()                # remove zero and negative counts
+    sum(c.values())                 # total of all counts
+    c.clear()                       # reset all counts
+    list(c)                         # list unique elements
+    set(c)                          # convert to a set
+    dict(c)                         # convert to a regular dictionary
+    c.items()                       # convert to a list of (elem, cnt) pairs
+    Counter(dict(list_of_pairs))    # convert from a list of (elem, cnt) pairs
+    c.most_common()[:-n:-1]         # n least common elements
+    c += Counter()                  # remove zero and negative counts
 
 Several multiset mathematical operations are provided for combining
 :class:`Counter` objects.  Multisets are like regular sets but are allowed to
@@ -258,13 +251,13 @@
 
     >>> c = Counter(a=3, b=1)
     >>> d = Counter(a=1, b=2)
-    >>> c + d                           # add two counters together:  c[x] + d[x]
+    >>> c + d                       # add two counters together:  c[x] + d[x]
     Counter({'a': 4, 'b': 3})
-    >>> c - d                           # subtract (keeping only positive counts)
+    >>> c - d                       # subtract (keeping only positive counts)
     Counter({'a': 2})
-    >>> c & d                           # intersection:  min(c[x], d[x])
+    >>> c & d                       # intersection:  min(c[x], d[x])
     Counter({'a': 1, 'b': 1})
-    >>> c | d                           # union:  max(c[x], d[x])
+    >>> c | d                       # union:  max(c[x], d[x])
     Counter({'a': 3, 'b': 2})
 
 .. seealso::
@@ -286,8 +279,7 @@
       Section 4.6.3, Exercise 19*\.
 
     * To enumerate all distinct multisets of a given size over a given set of
-      elements, see the :func:`combinations_with_replacement` function in the
-      :ref:`itertools-recipes` for itertools::
+      elements, see :func:`itertools.combinations_with_replacement`.
 
           map(Counter, combinations_with_replacement('ABC', 2)) --> AA AB AC BB BC CC
 

Modified: python/branches/py3k-issue1717/Doc/library/importlib.rst
==============================================================================
--- python/branches/py3k-issue1717/Doc/library/importlib.rst	(original)
+++ python/branches/py3k-issue1717/Doc/library/importlib.rst	Tue Jan 27 21:24:52 2009
@@ -95,12 +95,12 @@
     Only class methods are defined by this class to alleviate the need for
     instantiation.
 
-    .. method:: find_module(fullname, path=None)
+    .. classmethod:: find_module(fullname, path=None)
 
         Class method that allows this class to be a :term:`finder` for built-in
         modules.
 
-    .. method:: load_module(fullname)
+    .. classmethod:: load_module(fullname)
 
         Class method that allows this class to be a :term:`loader` for built-in
         modules.
@@ -113,12 +113,12 @@
     Only class methods are defined by this class to alleviate the need for
     instantiation.
 
-    .. method:: find_module(fullname, path=None)
+    .. classmethod:: find_module(fullname, path=None)
 
         Class method that allows this class to be a :term:`finder` for frozen
         modules.
 
-    .. method:: load_module(fullname)
+    .. classmethod:: load_module(fullname)
 
         Class method that allows this class to be a :term:`loader` for frozen
         modules.

Modified: python/branches/py3k-issue1717/Doc/library/itertools.rst
==============================================================================
--- python/branches/py3k-issue1717/Doc/library/itertools.rst	(original)
+++ python/branches/py3k-issue1717/Doc/library/itertools.rst	Tue Jan 27 21:24:52 2009
@@ -133,6 +133,67 @@
    The number of items returned is ``n! / r! / (n-r)!`` when ``0 <= r <= n``
    or zero when ``r > n``.
 
+.. function:: combinations_with_replacement(iterable, r)
+
+   Return *r* length subsequences of elements from the input *iterable*
+   allowing individual elements to be repeated more than once.
+
+   Combinations are emitted in lexicographic sort order.  So, if the
+   input *iterable* is sorted, the combination tuples will be produced
+   in sorted order.
+
+   Elements are treated as unique based on their position, not on their
+   value.  So if the input elements are unique, the generated combinations
+   will also be unique.
+
+   Equivalent to::
+
+        def combinations_with_replacement(iterable, r):
+            # combinations_with_replacement('ABC', 2) --> AA AB AC BB BC CC
+            pool = tuple(iterable)
+            n = len(pool)
+            if not n and r:
+                return
+            indices = [0] * r
+            yield tuple(pool[i] for i in indices)
+            while 1:
+                for i in reversed(range(r)):
+                    if indices[i] != n - 1:
+                        break
+                else:
+                    return
+                indices[i:] = [indices[i] + 1] * (r - i)
+                yield tuple(pool[i] for i in indices)
+
+   The code for :func:`combinations_with_replacement` can be also expressed as
+   a subsequence of :func:`product` after filtering entries where the elements
+   are not in sorted order (according to their position in the input pool)::
+
+        def combinations_with_replacement(iterable, r):
+            pool = tuple(iterable)
+            n = len(pool)
+            for indices in product(range(n), repeat=r):
+                if sorted(indices) == list(indices):
+                    yield tuple(pool[i] for i in indices)
+
+   The number of items returned is ``(n+r-1)! / r! / (n-1)!`` when ``n > 0``.
+
+   .. versionadded:: 2.7
+
+.. function:: compress(data, selectors)
+
+   Make an iterator that filters elements from *data* returning only those that
+   have a corresponding element in *selectors* that evaluates to ``True``.
+   Stops when either the *data* or *selectors* iterables have been exhausted.
+   Equivalent to::
+
+       def compress(data, selectors):
+           # compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F
+           return (d for d, s in zip(data, selectors) if s)
+
+   .. versionadded:: 2.7
+
+
 .. function:: count([n])
 
    Make an iterator that returns consecutive integers starting with *n*. If not
@@ -184,6 +245,20 @@
           for x in iterable:
               yield x
 
+.. function:: filterfalse(predicate, iterable)
+
+   Make an iterator that filters elements from iterable returning only those for
+   which the predicate is ``False``. If *predicate* is ``None``, return the items
+   that are false. Equivalent to::
+
+      def filterfalse(predicate, iterable):
+          # filterfalse(lambda x: x%2, range(10)) --> 0 2 4 6 8
+          if predicate is None:
+              predicate = bool
+          for x in iterable:
+              if not predicate(x):
+                  yield x
+
 
 .. function:: groupby(iterable[, key])
 
@@ -237,21 +312,6 @@
                   self.currkey = self.keyfunc(self.currvalue)
 
 
-.. function:: filterfalse(predicate, iterable)
-
-   Make an iterator that filters elements from iterable returning only those for
-   which the predicate is ``False``. If *predicate* is ``None``, return the items
-   that are false. Equivalent to::
-
-      def filterfalse(predicate, iterable):
-          # filterfalse(lambda x: x%2, range(10)) --> 0 2 4 6 8
-          if predicate is None:
-              predicate = bool
-          for x in iterable:
-              if not predicate(x):
-                  yield x
-
-
 .. function:: islice(iterable, [start,] stop [, step])
 
    Make an iterator that returns selected elements from the iterable. If *start* is
@@ -281,30 +341,6 @@
    then the step defaults to one.
 
 
-.. function:: zip_longest(*iterables[, fillvalue])
-
-   Make an iterator that aggregates elements from each of the iterables. If the
-   iterables are of uneven length, missing values are filled-in with *fillvalue*.
-   Iteration continues until the longest iterable is exhausted.  Equivalent to::
-
-      def zip_longest(*args, fillvalue=None):
-          # zip_longest('ABCD', 'xy', fillvalue='-') --> Ax By C- D-
-          def sentinel(counter = ([fillvalue]*(len(args)-1)).pop):
-              yield counter()         # yields the fillvalue, or raises IndexError
-          fillers = repeat(fillvalue)
-          iters = [chain(it, sentinel(), fillers) for it in args]
-          try:
-              for tup in zip(*iters):
-                  yield tup
-          except IndexError:
-              pass
-
-   If one of the iterables is potentially infinite, then the :func:`zip_longest`
-   function should be wrapped with something that limits the number of calls
-   (for example :func:`islice` or :func:`takewhile`).  If not specified,
-   *fillvalue* defaults to ``None``.
-
-
 .. function:: permutations(iterable[, r])
 
    Return successive *r* length permutations of elements in the *iterable*.
@@ -464,6 +500,30 @@
    is faster to use :func:`list` instead of :func:`tee`.
 
 
+.. function:: zip_longest(*iterables[, fillvalue])
+
+   Make an iterator that aggregates elements from each of the iterables. If the
+   iterables are of uneven length, missing values are filled-in with *fillvalue*.
+   Iteration continues until the longest iterable is exhausted.  Equivalent to::
+
+      def zip_longest(*args, fillvalue=None):
+          # zip_longest('ABCD', 'xy', fillvalue='-') --> Ax By C- D-
+          def sentinel(counter = ([fillvalue]*(len(args)-1)).pop):
+              yield counter()         # yields the fillvalue, or raises IndexError
+          fillers = repeat(fillvalue)
+          iters = [chain(it, sentinel(), fillers) for it in args]
+          try:
+              for tup in zip(*iters):
+                  yield tup
+          except IndexError:
+              pass
+
+   If one of the iterables is potentially infinite, then the :func:`zip_longest`
+   function should be wrapped with something that limits the number of calls
+   (for example :func:`islice` or :func:`takewhile`).  If not specified,
+   *fillvalue* defaults to ``None``.
+
+
 .. _itertools-example:
 
 Examples
@@ -574,7 +634,7 @@
    def grouper(n, iterable, fillvalue=None):
        "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx"
        args = [iter(iterable)] * n
-       return zip_longest(fillvalue=fillvalue, *args)
+       return zip_longest(*args, fillvalue=fillvalue)
 
    def roundrobin(*iterables):
        "roundrobin('ABC', 'D', 'EF') --> A D E B F C"
@@ -590,31 +650,9 @@
                nexts = cycle(islice(nexts, pending))
 
    def powerset(iterable):
-       "powerset('ab') --> set([]), set(['a']), set(['b']), set(['a', 'b'])"
-       # Recipe credited to Eric Raymond
-       pairs = [(2**i, x) for i, x in enumerate(iterable)]
-       for n in xrange(2**len(pairs)):
-           yield set(x for m, x in pairs if m&n)
-
-   def compress(data, selectors):
-       "compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F"
-       return (d for d, s in zip(data, selectors) if s)
-
-   def combinations_with_replacement(iterable, r):
-       "combinations_with_replacement('ABC', 2) --> AA AB AC BB BC CC"
-       # number items returned:  (n+r-1)! / r! / (n-1)!
-       pool = tuple(iterable)
-       n = len(pool)
-       indices = [0] * r
-       yield tuple(pool[i] for i in indices)
-       while True:
-           for i in reversed(range(r)):
-               if indices[i] != n - 1:
-                   break
-           else:
-               return
-           indices[i:] = [indices[i] + 1] * (r - i)
-           yield tuple(pool[i] for i in indices)
+       "powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)"
+       s = list(iterable)
+       return chain.from_iterable(combinations(s, r) for r in range(len(s)+1))
 
     def unique_everseen(iterable, key=None):
         "List unique elements, preserving order. Remember all elements ever seen."

Modified: python/branches/py3k-issue1717/Doc/library/operator.rst
==============================================================================
--- python/branches/py3k-issue1717/Doc/library/operator.rst	(original)
+++ python/branches/py3k-issue1717/Doc/library/operator.rst	Tue Jan 27 21:24:52 2009
@@ -221,12 +221,6 @@
    Return the index of the first of occurrence of *b* in *a*.
 
 
-.. function:: repeat(a, b)
-              __repeat__(a, b)
-
-   Return ``a * b`` where *a* is a sequence and *b* is an integer.
-
-
 .. function:: setitem(a, b, c)
               __setitem__(a, b, c)
 
@@ -294,13 +288,6 @@
    ``a = ipow(a, b)`` is equivalent to ``a **= b``.
 
 
-.. function:: irepeat(a, b)
-              __irepeat__(a, b)
-
-   ``a = irepeat(a, b)`` is equivalent to ``a *= b`` where *a* is a sequence and
-   *b* is an integer.
-
-
 .. function:: irshift(a, b)
               __irshift__(a, b)
 
@@ -324,67 +311,6 @@
 
    ``a = ixor(a, b)`` is equivalent to ``a ^= b``.
 
-
-The :mod:`operator` module also defines a few predicates to test the type of
-objects.
-
-.. XXX just remove them?
-.. note::
-
-   Be careful not to misinterpret the results of these functions; none have any
-   measure of reliability with instance objects.
-   For example:
-
-      >>> class C:
-      ...     pass
-      ...
-      >>> import operator
-      >>> obj = C()
-      >>> operator.isMappingType(obj)
-      True
-
-.. note::
-
-   Since there are now abstract classes for collection types, you should write,
-   for example, ``isinstance(obj, collections.Mapping)`` and ``isinstance(obj,
-   collections.Sequence)``.
-
-.. function:: isMappingType(obj)
-
-   Returns true if the object *obj* supports the mapping interface. This is true for
-   dictionaries and all instance objects defining :meth:`__getitem__`.
-
-   .. warning::
-
-      There is no reliable way to test if an instance supports the complete mapping
-      protocol since the interface itself is ill-defined.  This makes this test less
-      useful than it otherwise might be.
-
-
-.. function:: isNumberType(obj)
-
-   Returns true if the object *obj* represents a number.  This is true for all
-   numeric types implemented in C.
-
-   .. warning::
-
-      There is no reliable way to test if an instance supports the complete numeric
-      interface since the interface itself is ill-defined.  This makes this test less
-      useful than it otherwise might be.
-
-
-.. function:: isSequenceType(obj)
-
-   Returns true if the object *obj* supports the sequence protocol. This returns true
-   for all objects which define sequence methods in C, and for all instance objects
-   defining :meth:`__getitem__`.
-
-   .. warning::
-
-      There is no reliable way to test if an instance supports the complete sequence
-      interface since the interface itself is ill-defined.  This makes this test less
-      useful than it otherwise might be.
-
 Example: Build a dictionary that maps the ordinals from ``0`` to ``255`` to
 their character equivalents.
 
@@ -513,8 +439,6 @@
 +-----------------------+-------------------------+---------------------------------+
 | Right Shift           | ``a >> b``              | ``rshift(a, b)``                |
 +-----------------------+-------------------------+---------------------------------+
-| Sequence Repetition   | ``seq * i``             | ``repeat(seq, i)``              |
-+-----------------------+-------------------------+---------------------------------+
 | String Formatting     | ``s % obj``             | ``mod(s, obj)``                 |
 +-----------------------+-------------------------+---------------------------------+
 | Subtraction           | ``a - b``               | ``sub(a, b)``                   |

Modified: python/branches/py3k-issue1717/Lib/collections.py
==============================================================================
--- python/branches/py3k-issue1717/Lib/collections.py	(original)
+++ python/branches/py3k-issue1717/Lib/collections.py	Tue Jan 27 21:24:52 2009
@@ -111,7 +111,7 @@
     # where the named tuple is created.  Bypass this step in enviroments where
     # sys._getframe is not defined (Jython for example).
     if hasattr(_sys, '_getframe'):
-        result.__module__ = _sys._getframe(1).f_globals['__name__']
+        result.__module__ = _sys._getframe(1).f_globals.get('__name__', '__main__')
 
     return result
 

Modified: python/branches/py3k-issue1717/Lib/ctypes/test/test_libc.py
==============================================================================
--- python/branches/py3k-issue1717/Lib/ctypes/test/test_libc.py	(original)
+++ python/branches/py3k-issue1717/Lib/ctypes/test/test_libc.py	Tue Jan 27 21:24:52 2009
@@ -5,7 +5,8 @@
 
 lib = CDLL(_ctypes_test.__file__)
 
-def twcmp(x, y):
+def three_way_cmp(x, y):
+    """Return -1 if x < y, 0 if x == y and 1 if x > y"""
     return (x > y) - (x < y)
 
 class LibTest(unittest.TestCase):
@@ -22,7 +23,7 @@
         lib.my_qsort.restype = None
 
         def sort(a, b):
-            return twcmp(a[0], b[0])
+            return three_way_cmp(a[0], b[0])
 
         chars = create_string_buffer("spam, spam, and spam")
         lib.my_qsort(chars, len(chars)-1, sizeof(c_char), comparefunc(sort))

Modified: python/branches/py3k-issue1717/Lib/distutils/ccompiler.py
==============================================================================
--- python/branches/py3k-issue1717/Lib/distutils/ccompiler.py	(original)
+++ python/branches/py3k-issue1717/Lib/distutils/ccompiler.py	Tue Jan 27 21:24:52 2009
@@ -1004,7 +1004,6 @@
     # OS name mappings
     ('posix', 'unix'),
     ('nt', 'msvc'),
-    ('mac', 'mwerks'),
 
     )
 
@@ -1042,8 +1041,6 @@
                                "Mingw32 port of GNU C Compiler for Win32"),
                    'bcpp':    ('bcppcompiler', 'BCPPCompiler',
                                "Borland C++ Compiler"),
-                   'mwerks':  ('mwerkscompiler', 'MWerksCompiler',
-                               "MetroWerks CodeWarrior"),
                    'emx':     ('emxccompiler', 'EMXCCompiler',
                                "EMX port of GNU C Compiler for OS/2"),
                  }

Modified: python/branches/py3k-issue1717/Lib/distutils/command/sdist.py
==============================================================================
--- python/branches/py3k-issue1717/Lib/distutils/command/sdist.py	(original)
+++ python/branches/py3k-issue1717/Lib/distutils/command/sdist.py	Tue Jan 27 21:24:52 2009
@@ -428,6 +428,10 @@
 
         self.make_release_tree(base_dir, self.filelist.files)
         archive_files = []              # remember names of files we create
+        # tar archive must be created last to avoid overwrite and remove
+        if 'tar' in self.formats:
+            self.formats.append(self.formats.pop(self.formats.index('tar')))
+
         for fmt in self.formats:
             file = self.make_archive(base_name, fmt, base_dir=base_dir)
             archive_files.append(file)

Deleted: python/branches/py3k-issue1717/Lib/distutils/mwerkscompiler.py
==============================================================================
--- python/branches/py3k-issue1717/Lib/distutils/mwerkscompiler.py	Tue Jan 27 21:24:52 2009
+++ (empty file)
@@ -1,245 +0,0 @@
-"""distutils.mwerkscompiler
-
-Contains MWerksCompiler, an implementation of the abstract CCompiler class
-for MetroWerks CodeWarrior on the Macintosh. Needs work to support CW on
-Windows."""
-
-__revision__ = "$Id$"
-
-import sys, os
-from distutils.errors import \
-     DistutilsExecError, DistutilsPlatformError, \
-     CompileError, LibError, LinkError
-from distutils.ccompiler import \
-     CCompiler, gen_preprocess_options, gen_lib_options
-import distutils.util
-import distutils.dir_util
-from distutils import log
-
-class MWerksCompiler (CCompiler) :
-    """Concrete class that implements an interface to MetroWerks CodeWarrior,
-       as defined by the CCompiler abstract class."""
-
-    compiler_type = 'mwerks'
-
-    # Just set this so CCompiler's constructor doesn't barf.  We currently
-    # don't use the 'set_executables()' bureaucracy provided by CCompiler,
-    # as it really isn't necessary for this sort of single-compiler class.
-    # Would be nice to have a consistent interface with UnixCCompiler,
-    # though, so it's worth thinking about.
-    executables = {}
-
-    # Private class data (need to distinguish C from C++ source for compiler)
-    _c_extensions = ['.c']
-    _cpp_extensions = ['.cc', '.cpp', '.cxx']
-    _rc_extensions = ['.r']
-    _exp_extension = '.exp'
-
-    # Needed for the filename generation methods provided by the
-    # base class, CCompiler.
-    src_extensions = (_c_extensions + _cpp_extensions +
-                      _rc_extensions)
-    res_extension = '.rsrc'
-    obj_extension = '.obj' # Not used, really
-    static_lib_extension = '.lib'
-    shared_lib_extension = '.slb'
-    static_lib_format = shared_lib_format = '%s%s'
-    exe_extension = ''
-
-
-    def __init__ (self,
-                  verbose=0,
-                  dry_run=0,
-                  force=0):
-
-        CCompiler.__init__ (self, verbose, dry_run, force)
-
-
-    def compile (self,
-                 sources,
-                 output_dir=None,
-                 macros=None,
-                 include_dirs=None,
-                 debug=0,
-                 extra_preargs=None,
-                 extra_postargs=None,
-                 depends=None):
-        (output_dir, macros, include_dirs) = \
-           self._fix_compile_args (output_dir, macros, include_dirs)
-        self.__sources = sources
-        self.__macros = macros
-        self.__include_dirs = include_dirs
-        # Don't need extra_preargs and extra_postargs for CW
-        return []
-
-    def link (self,
-              target_desc,
-              objects,
-              output_filename,
-              output_dir=None,
-              libraries=None,
-              library_dirs=None,
-              runtime_library_dirs=None,
-              export_symbols=None,
-              debug=0,
-              extra_preargs=None,
-              extra_postargs=None,
-              build_temp=None,
-              target_lang=None):
-        # First fixup.
-        (objects, output_dir) = self._fix_object_args (objects, output_dir)
-        (libraries, library_dirs, runtime_library_dirs) = \
-            self._fix_lib_args (libraries, library_dirs, runtime_library_dirs)
-
-        # First examine a couple of options for things that aren't implemented yet
-        if not target_desc in (self.SHARED_LIBRARY, self.SHARED_OBJECT):
-            raise DistutilsPlatformError('Can only make SHARED_LIBRARY or SHARED_OBJECT targets on the Mac')
-        if runtime_library_dirs:
-            raise DistutilsPlatformError('Runtime library dirs not implemented yet')
-        if extra_preargs or extra_postargs:
-            raise DistutilsPlatformError('Runtime library dirs not implemented yet')
-        if len(export_symbols) != 1:
-            raise DistutilsPlatformError('Need exactly one export symbol')
-        # Next there are various things for which we need absolute pathnames.
-        # This is because we (usually) create the project in a subdirectory of
-        # where we are now, and keeping the paths relative is too much work right
-        # now.
-        sources = [self._filename_to_abs(s) for s in self.__sources]
-        include_dirs = [self._filename_to_abs(d) for d in self.__include_dirs]
-        if objects:
-            objects = [self._filename_to_abs(o) for o in objects]
-        else:
-            objects = []
-        if build_temp:
-            build_temp = self._filename_to_abs(build_temp)
-        else:
-            build_temp = os.curdir()
-        if output_dir:
-            output_filename = os.path.join(output_dir, output_filename)
-        # The output filename needs special handling: splitting it into dir and
-        # filename part. Actually I'm not sure this is really needed, but it
-        # can't hurt.
-        output_filename = self._filename_to_abs(output_filename)
-        output_dir, output_filename = os.path.split(output_filename)
-        # Now we need the short names of a couple of things for putting them
-        # into the project.
-        if output_filename[-8:] == '.ppc.slb':
-            basename = output_filename[:-8]
-        elif output_filename[-11:] == '.carbon.slb':
-            basename = output_filename[:-11]
-        else:
-            basename = os.path.strip(output_filename)[0]
-        projectname = basename + '.mcp'
-        targetname = basename
-        xmlname = basename + '.xml'
-        exportname = basename + '.mcp.exp'
-        prefixname = 'mwerks_%s_config.h'%basename
-        # Create the directories we need
-        distutils.dir_util.mkpath(build_temp, dry_run=self.dry_run)
-        distutils.dir_util.mkpath(output_dir, dry_run=self.dry_run)
-        # And on to filling in the parameters for the project builder
-        settings = {}
-        settings['mac_exportname'] = exportname
-        settings['mac_outputdir'] = output_dir
-        settings['mac_dllname'] = output_filename
-        settings['mac_targetname'] = targetname
-        settings['sysprefix'] = sys.prefix
-        settings['mac_sysprefixtype'] = 'Absolute'
-        sourcefilenames = []
-        sourcefiledirs = []
-        for filename in sources + objects:
-            dirname, filename = os.path.split(filename)
-            sourcefilenames.append(filename)
-            if not dirname in sourcefiledirs:
-                sourcefiledirs.append(dirname)
-        settings['sources'] = sourcefilenames
-        settings['libraries'] = libraries
-        settings['extrasearchdirs'] = sourcefiledirs + include_dirs + library_dirs
-        if self.dry_run:
-            print('CALLING LINKER IN', os.getcwd())
-            for key, value in settings.items():
-                print('%20.20s %s'%(key, value))
-            return
-        # Build the export file
-        exportfilename = os.path.join(build_temp, exportname)
-        log.debug("\tCreate export file %s", exportfilename)
-        fp = open(exportfilename, 'w')
-        fp.write('%s\n'%export_symbols[0])
-        fp.close()
-        # Generate the prefix file, if needed, and put it in the settings
-        if self.__macros:
-            prefixfilename = os.path.join(os.getcwd(), os.path.join(build_temp, prefixname))
-            fp = open(prefixfilename, 'w')
-            fp.write('#include "mwerks_shcarbon_config.h"\n')
-            for name, value in self.__macros:
-                if value is None:
-                    fp.write('#define %s\n'%name)
-                else:
-                    fp.write('#define %s %s\n'%(name, value))
-            fp.close()
-            settings['prefixname'] = prefixname
-
-        # Build the XML file. We need the full pathname (only lateron, really)
-        # because we pass this pathname to CodeWarrior in an AppleEvent, and CW
-        # doesn't have a clue about our working directory.
-        xmlfilename = os.path.join(os.getcwd(), os.path.join(build_temp, xmlname))
-        log.debug("\tCreate XML file %s", xmlfilename)
-        import mkcwproject
-        xmlbuilder = mkcwproject.cwxmlgen.ProjectBuilder(settings)
-        xmlbuilder.generate()
-        xmldata = settings['tmp_projectxmldata']
-        fp = open(xmlfilename, 'w')
-        fp.write(xmldata)
-        fp.close()
-        # Generate the project. Again a full pathname.
-        projectfilename = os.path.join(os.getcwd(), os.path.join(build_temp, projectname))
-        log.debug('\tCreate project file %s', projectfilename)
-        mkcwproject.makeproject(xmlfilename, projectfilename)
-        # And build it
-        log.debug('\tBuild project')
-        mkcwproject.buildproject(projectfilename)
-
-    def _filename_to_abs(self, filename):
-        # Some filenames seem to be unix-like. Convert to Mac names.
-##        if '/' in filename and ':' in filename:
-##           raise DistutilsPlatformError, 'Filename may be Unix or Mac style: %s'%filename
-##        if '/' in filename:
-##           filename = macurl2path(filename)
-        filename = distutils.util.convert_path(filename)
-        if not os.path.isabs(filename):
-            curdir = os.getcwd()
-            filename = os.path.join(curdir, filename)
-        # Finally remove .. components
-        components = filename.split(':')
-        for i in range(1, len(components)):
-            if components[i] == '..':
-                components[i] = ''
-        return ':'.join(components)
-
-    def library_dir_option (self, dir):
-        """Return the compiler option to add 'dir' to the list of
-        directories searched for libraries.
-        """
-        return # XXXX Not correct...
-
-    def runtime_library_dir_option (self, dir):
-        """Return the compiler option to add 'dir' to the list of
-        directories searched for runtime libraries.
-        """
-        # Nothing needed or Mwerks/Mac.
-        return
-
-    def library_option (self, lib):
-        """Return the compiler option to add 'dir' to the list of libraries
-        linked into the shared library or executable.
-        """
-        return
-
-    def find_library_file (self, dirs, lib, debug=0):
-        """Search the specified list of directories for a static or shared
-        library file 'lib' and return the full path to that file.  If
-        'debug' true, look for a debugging version (if that makes sense on
-        the current platform).  Return None if 'lib' wasn't found in any of
-        the specified directories.
-        """
-        return 0

Modified: python/branches/py3k-issue1717/Lib/distutils/tests/test_sdist.py
==============================================================================
--- python/branches/py3k-issue1717/Lib/distutils/tests/test_sdist.py	(original)
+++ python/branches/py3k-issue1717/Lib/distutils/tests/test_sdist.py	Tue Jan 27 21:24:52 2009
@@ -4,10 +4,13 @@
 import shutil
 import zipfile
 from os.path import join
+import sys
 
 from distutils.command.sdist import sdist
 from distutils.core import Distribution
 from distutils.tests.test_config import PyPIRCCommandTestCase
+from distutils.errors import DistutilsExecError
+from distutils.spawn import spawn
 
 CURDIR = os.path.dirname(__file__)
 TEMP_PKG = join(CURDIR, 'temppkg')
@@ -35,6 +38,19 @@
             shutil.rmtree(TEMP_PKG)
         PyPIRCCommandTestCase.tearDown(self)
 
+    def _init_tmp_pkg(self):
+        if os.path.exists(TEMP_PKG):
+            shutil.rmtree(TEMP_PKG)
+        os.mkdir(TEMP_PKG)
+        os.mkdir(join(TEMP_PKG, 'somecode'))
+        os.mkdir(join(TEMP_PKG, 'dist'))
+        # creating a MANIFEST, a package, and a README
+        self._write(join(TEMP_PKG, 'MANIFEST.in'), MANIFEST_IN)
+        self._write(join(TEMP_PKG, 'README'), 'xxx')
+        self._write(join(TEMP_PKG, 'somecode', '__init__.py'), '#')
+        self._write(join(TEMP_PKG, 'setup.py'), SETUP_PY)
+        os.chdir(TEMP_PKG)
+
     def _write(self, path, content):
         f = open(path, 'w')
         try:
@@ -46,15 +62,7 @@
         # this test creates a package with some vcs dirs in it
         # and launch sdist to make sure they get pruned
         # on all systems
-        if not os.path.exists(TEMP_PKG):
-            os.mkdir(TEMP_PKG)
-        os.mkdir(join(TEMP_PKG, 'somecode'))
-
-        # creating a MANIFEST, a package, and a README
-        self._write(join(TEMP_PKG, 'MANIFEST.in'), MANIFEST_IN)
-        self._write(join(TEMP_PKG, 'README'), 'xxx')
-        self._write(join(TEMP_PKG, 'somecode', '__init__.py'), '#')
-        self._write(join(TEMP_PKG, 'setup.py'), SETUP_PY)
+        self._init_tmp_pkg()
 
         # creating VCS directories with some files in them
         os.mkdir(join(TEMP_PKG, 'somecode', '.svn'))
@@ -68,8 +76,6 @@
         self._write(join(TEMP_PKG, 'somecode', '.git',
                          'ok'), 'xxx')
 
-        os.chdir(TEMP_PKG)
-
         # now building a sdist
         dist = Distribution()
         dist.script_name = 'setup.py'
@@ -103,6 +109,55 @@
         # making sure everything has been pruned correctly
         self.assertEquals(len(content), 4)
 
+    def test_make_distribution(self):
+
+        self._init_tmp_pkg()
+
+        # check if tar is installed under win32
+        if sys.platform == 'win32':
+            try:
+                spawn('tar --help')
+            except DistutilsExecError:
+                # let's return, no need to go further
+                return
+
+        # now building a sdist
+        dist = Distribution()
+        dist.script_name = 'setup.py'
+        dist.metadata.name = 'fake'
+        dist.metadata.version = '1.0'
+        dist.metadata.url = 'http://xxx'
+        dist.metadata.author = dist.metadata.author_email = 'xxx'
+        dist.packages = ['somecode']
+        dist.include_package_data = True
+        cmd = sdist(dist)
+        cmd.manifest = 'MANIFEST'
+        cmd.template = 'MANIFEST.in'
+        cmd.dist_dir = 'dist'
+
+        # creating a gztar then a tar
+        cmd.formats = ['gztar', 'tar']
+        cmd.run()
+
+        # making sure we have two files
+        dist_folder = join(TEMP_PKG, 'dist')
+        result = os.listdir(dist_folder)
+        result.sort()
+        self.assertEquals(result,
+                          ['fake-1.0.tar', 'fake-1.0.tar.gz'] )
+
+        os.remove(join(dist_folder, 'fake-1.0.tar'))
+        os.remove(join(dist_folder, 'fake-1.0.tar.gz'))
+
+        # now trying a tar then a gztar
+        cmd.formats = ['tar', 'gztar']
+        cmd.run()
+
+        result = os.listdir(dist_folder)
+        result.sort()
+        self.assertEquals(result,
+                ['fake-1.0.tar', 'fake-1.0.tar.gz'])
+
 def test_suite():
     return unittest.makeSuite(sdistTestCase)
 

Modified: python/branches/py3k-issue1717/Lib/doctest.py
==============================================================================
--- python/branches/py3k-issue1717/Lib/doctest.py	(original)
+++ python/branches/py3k-issue1717/Lib/doctest.py	Tue Jan 27 21:24:52 2009
@@ -837,6 +837,8 @@
             globs = globs.copy()
         if extraglobs is not None:
             globs.update(extraglobs)
+        if '__name__' not in globs:
+            globs['__name__'] = '__main__'  # provide a default module name
 
         # Recursively expore `obj`, extracting DocTests.
         tests = []
@@ -1947,6 +1949,8 @@
         globs = globs.copy()
     if extraglobs is not None:
         globs.update(extraglobs)
+    if '__name__' not in globs:
+        globs['__name__'] = '__main__'
 
     if raise_on_error:
         runner = DebugRunner(verbose=verbose, optionflags=optionflags)

Modified: python/branches/py3k-issue1717/Lib/idlelib/PyShell.py
==============================================================================
--- python/branches/py3k-issue1717/Lib/idlelib/PyShell.py	(original)
+++ python/branches/py3k-issue1717/Lib/idlelib/PyShell.py	Tue Jan 27 21:24:52 2009
@@ -963,15 +963,6 @@
     COPYRIGHT = \
           'Type "copyright", "credits" or "license()" for more information.'
 
-    firewallmessage = """
-    ****************************************************************
-    Personal firewall software may warn about the connection IDLE
-    makes to its subprocess using this computer's internal loopback
-    interface.  This connection is not visible on any external
-    interface and no data is sent to or received from the Internet.
-    ****************************************************************
-    """
-
     def begin(self):
         self.text.mark_set("iomark", "insert")
         self.resetoutput()
@@ -983,9 +974,8 @@
                 return False
         else:
             nosub = "==== No Subprocess ===="
-        self.write("Python %s on %s\n%s\n%s\nIDLE %s      %s\n" %
-                   (sys.version, sys.platform, self.COPYRIGHT,
-                    self.firewallmessage, idlever.IDLE_VERSION, nosub))
+        self.write("Python %s on %s\n%s\n%s" %
+                   (sys.version, sys.platform, self.COPYRIGHT, nosub))
         self.showprompt()
         import tkinter
         tkinter._default_root = None # 03Jan04 KBK What's this?

Modified: python/branches/py3k-issue1717/Lib/importlib/NOTES
==============================================================================
--- python/branches/py3k-issue1717/Lib/importlib/NOTES	(original)
+++ python/branches/py3k-issue1717/Lib/importlib/NOTES	Tue Jan 27 21:24:52 2009
@@ -1,19 +1,12 @@
 to do
 /////
 
-* Expose resolve_name().
+* Use test.loader_tests
 
-* Backport to Python 2.7.
-
-    + import_module
-    + resolve_name
-
-* Create reasonable base tests that all finders and loaders must pass so
-  that various implementations can just subclass as needed.
-
-* Expose built-in and frozen importers.
-
-    + Make staticmethods so that class can be used directly.
+    + builtin
+    + frozen
+    + extension
+    + source
 
 * Reorganize support code.
 
@@ -31,13 +24,6 @@
     + write_bytecode -> complete set of bytes for bytecode instead of
       individual arguments.
 
-* Implement PEP 302 protocol for loaders (should just be a matter of testing).
-
-    + Built-in.
-    + Frozen.
-    + Extension.
-    + Source/bytecode.
-
 * Create meta_path importer for sys.path.
 
 * OPTIMIZE!
@@ -48,6 +34,13 @@
     - Absolute name from sys.path.
     - Relative name from sys.path.
 
+* Implement PEP 302 protocol for loaders (should just be a matter of testing).
+
+    + Built-in.
+    + Frozen.
+    + Extension.
+    + Source/bytecode.
+
 * Public API to expose (w/ docs!)
 
   + abc
@@ -80,6 +73,7 @@
 
       - get_module decorator (new name)
       - check_name decorator (new name)
+      - resolve_name
 
   + machinery
 

Modified: python/branches/py3k-issue1717/Lib/importlib/test/builtin/test_finder.py
==============================================================================
--- python/branches/py3k-issue1717/Lib/importlib/test/builtin/test_finder.py	(original)
+++ python/branches/py3k-issue1717/Lib/importlib/test/builtin/test_finder.py	Tue Jan 27 21:24:52 2009
@@ -1,29 +1,48 @@
 from importlib import machinery
+from .. import finder_tests
 from .. import support
 
 import sys
 import unittest
 
-class FinderTests(unittest.TestCase):
+class FinderTests(finder_tests.FinderTests):
 
     """Test find_module() for built-in modules."""
 
     assert 'errno' in sys.builtin_module_names
     name = 'errno'
 
-    find_module = staticmethod(lambda name, path=None:
-                    machinery.BuiltinImporter.find_module(name, path))
-
-
-    def test_find_module(self):
+    def test_module(self):
         # Common case.
         with support.uncache(self.name):
-            self.assert_(self.find_module(self.name))
+            self.assert_(machinery.BuiltinImporter.find_module(self.name))
+
+    def test_package(self):
+        # Built-in modules cannot be a package.
+        pass
+
+    def test_module_in_package(self):
+        # Built-in modules cannobt be in a package.
+        pass
+
+    def test_package_in_package(self):
+        # Built-in modules cannot be a package.
+        pass
+
+    def test_package_over_module(self):
+        # Built-in modules cannot be a package.
+        pass
+
+    def test_failure(self):
+        assert 'importlib' not in sys.builtin_module_names
+        loader = machinery.BuiltinImporter.find_module('importlib')
+        self.assert_(loader is None)
 
     def test_ignore_path(self):
         # The value for 'path' should always trigger a failed import.
         with support.uncache(self.name):
-            self.assert_(self.find_module(self.name, ['pkg']) is None)
+            loader = machinery.BuiltinImporter.find_module(self.name, ['pkg'])
+            self.assert_(loader is None)
 
 
 

Modified: python/branches/py3k-issue1717/Lib/importlib/test/extension/test_finder.py
==============================================================================
--- python/branches/py3k-issue1717/Lib/importlib/test/extension/test_finder.py	(original)
+++ python/branches/py3k-issue1717/Lib/importlib/test/extension/test_finder.py	Tue Jan 27 21:24:52 2009
@@ -1,9 +1,10 @@
 import importlib
+from .. import finder_tests
 from . import test_path_hook
 
 import unittest
 
-class FinderTests(unittest.TestCase):
+class FinderTests(finder_tests.FinderTests):
 
     """Test the finder for extension modules."""
 
@@ -11,9 +12,25 @@
         importer = importlib.ExtensionFileImporter(test_path_hook.PATH)
         return importer.find_module(fullname)
 
-    def test_success(self):
+    def test_module(self):
         self.assert_(self.find_module(test_path_hook.NAME))
 
+    def test_package(self):
+        # Extension modules cannot be an __init__ for a package.
+        pass
+
+    def test_module_in_package(self):
+        # No extension module in a package available for testing.
+        pass
+
+    def test_package_in_package(self):
+        # Extension modules cannot be an __init__ for a package.
+        pass
+
+    def test_package_over_module(self):
+        # Extension modules cannot be an __init__ for a package.
+        pass
+
     def test_failure(self):
         self.assert_(self.find_module('asdfjkl;') is None)
 

Modified: python/branches/py3k-issue1717/Lib/importlib/test/finder_tests.py
==============================================================================
--- python/branches/py3k-issue1717/Lib/importlib/test/finder_tests.py	(original)
+++ python/branches/py3k-issue1717/Lib/importlib/test/finder_tests.py	Tue Jan 27 21:24:52 2009
@@ -1,39 +1,39 @@
-# top-level.
-# Package.
-# module in pacakge.
-# Package within a package.
-# At least one tests with 'path'.
-# Module that is not handled.
-
+import abc
 import unittest
 
 
-class FinderTests(unittest.TestCase):
+class FinderTests(unittest.TestCase, metaclass=abc.ABCMeta):
 
     """Basic tests for a finder to pass."""
 
+    @abc.abstractmethod
     def test_module(self):
         # Test importing a top-level module.
-        raise NotImplementedError
+        pass
 
+    @abc.abstractmethod
     def test_package(self):
         # Test importing a package.
-        raise NotImplementedError
+        pass
 
+    @abc.abstractmethod
     def test_module_in_package(self):
         # Test importing a module contained within a package.
         # A value for 'path' should be used if for a meta_path finder.
-        raise NotImplementedError
+        pass
 
+    @abc.abstractmethod
     def test_package_in_package(self):
         # Test importing a subpackage.
         # A value for 'path' should be used if for a meta_path finder.
-        raise NotImplementedError
+        pass
 
+    @abc.abstractmethod
     def test_package_over_module(self):
         # Test that packages are chosen over modules.
-        raise NotImplementedError
+        pass
 
+    @abc.abstractmethod
     def test_failure(self):
         # Test trying to find a module that cannot be handled.
-        raise NotImplementedError
+        pass

Modified: python/branches/py3k-issue1717/Lib/importlib/test/frozen/test_finder.py
==============================================================================
--- python/branches/py3k-issue1717/Lib/importlib/test/frozen/test_finder.py	(original)
+++ python/branches/py3k-issue1717/Lib/importlib/test/frozen/test_finder.py	Tue Jan 27 21:24:52 2009
@@ -1,11 +1,10 @@
-from importlib import machinery
-from ..builtin import test_finder
-from .. import support
+from ... import machinery
+from .. import finder_tests
 
 import unittest
 
 
-class FinderTests(test_finder.FinderTests):
+class FinderTests(finder_tests.FinderTests):
 
     """Test finding frozen modules."""
 
@@ -13,7 +12,6 @@
         finder = machinery.FrozenImporter
         return finder.find_module(name, path)
 
-
     def test_module(self):
         name = '__hello__'
         loader = self.find(name)
@@ -28,6 +26,11 @@
         self.assert_(hasattr(loader, 'load_module'))
 
     def test_package_in_package(self):
+        # No frozen package within another package to test with.
+        pass
+
+    def test_package_over_module(self):
+        # No easy way to test.
         pass
 
     def test_failure(self):

Modified: python/branches/py3k-issue1717/Lib/locale.py
==============================================================================
--- python/branches/py3k-issue1717/Lib/locale.py	(original)
+++ python/branches/py3k-issue1717/Lib/locale.py	Tue Jan 27 21:24:52 2009
@@ -187,7 +187,7 @@
             formatted = _group(formatted, monetary=monetary)[0]
     return formatted
 
-import re, operator
+import re, collections
 _percent_re = re.compile(r'%(?:\((?P<key>.*?)\))?'
                          r'(?P<modifiers>[-#0-9 +*.hlL]*?)[eEfFgGdiouxXcrs%]')
 
@@ -207,7 +207,7 @@
             del new_val[i+1:i+1+starcount]
             i += (1 + starcount)
         val = tuple(new_val)
-    elif operator.isMappingType(val):
+    elif isinstance(val, collections.Mapping):
         for perc in percents:
             key = perc.group("key")
             val[key] = format(perc.group(), val[key], grouping)

Modified: python/branches/py3k-issue1717/Lib/test/test_array.py
==============================================================================
--- python/branches/py3k-issue1717/Lib/test/test_array.py	(original)
+++ python/branches/py3k-issue1717/Lib/test/test_array.py	Tue Jan 27 21:24:52 2009
@@ -725,8 +725,8 @@
         self.assertRaises(BufferError, operator.setitem, a, slice(0, 0), a)
         self.assertRaises(BufferError, operator.delitem, a, 0)
         self.assertRaises(BufferError, operator.delitem, a, slice(0, 1))
-        self.assertRaises(BufferError, operator.irepeat, a, 2)
-        self.assertRaises(BufferError, operator.irepeat, a, 0)
+        self.assertRaises(BufferError, operator.imul, a, 2)
+        self.assertRaises(BufferError, operator.imul, a, 0)
 
     def test_weakref(self):
         s = array.array(self.typecode, self.example)

Modified: python/branches/py3k-issue1717/Lib/test/test_bool.py
==============================================================================
--- python/branches/py3k-issue1717/Lib/test/test_bool.py	(original)
+++ python/branches/py3k-issue1717/Lib/test/test_bool.py	Tue Jan 27 21:24:52 2009
@@ -245,16 +245,10 @@
         import operator
         self.assertIs(operator.truth(0), False)
         self.assertIs(operator.truth(1), True)
-        self.assertIs(operator.isNumberType(None), False)
-        self.assertIs(operator.isNumberType(0), True)
         self.assertIs(operator.not_(1), False)
         self.assertIs(operator.not_(0), True)
-        self.assertIs(operator.isSequenceType(0), False)
-        self.assertIs(operator.isSequenceType([]), True)
         self.assertIs(operator.contains([], 1), False)
         self.assertIs(operator.contains([1], 1), True)
-        self.assertIs(operator.isMappingType(1), False)
-        self.assertIs(operator.isMappingType({}), True)
         self.assertIs(operator.lt(0, 0), False)
         self.assertIs(operator.lt(0, 1), True)
         self.assertIs(operator.is_(True, True), True)

Modified: python/branches/py3k-issue1717/Lib/test/test_cmd_line.py
==============================================================================
--- python/branches/py3k-issue1717/Lib/test/test_cmd_line.py	(original)
+++ python/branches/py3k-issue1717/Lib/test/test_cmd_line.py	Tue Jan 27 21:24:52 2009
@@ -159,6 +159,16 @@
             self.assertEqual(data.strip(), b'x',
                 "text %s not line-buffered" % stream)
 
+    def test_unbuffered_input(self):
+        # sys.stdin still works with '-u'
+        code = ("import sys; sys.stdout.write(sys.stdin.read(1))")
+        p = _spawn_python('-u', '-c', code)
+        p.stdin.write(b'x')
+        p.stdin.flush()
+        data, rc = _kill_python_and_exit_code(p)
+        self.assertEqual(rc, 0)
+        self.assert_(data.startswith(b'x'), data)
+
 
 def test_main():
     test.support.run_unittest(CmdLineTest)

Modified: python/branches/py3k-issue1717/Lib/test/test_contains.py
==============================================================================
--- python/branches/py3k-issue1717/Lib/test/test_contains.py	(original)
+++ python/branches/py3k-issue1717/Lib/test/test_contains.py	Tue Jan 27 21:24:52 2009
@@ -56,31 +56,16 @@
             This class is designed to make sure that the contains code
             works when the list is modified during the check.
             """
-            aList = range(15)
-            def __lt__(self, other):
+            aList = list(range(15))
+            def __eq__(self, other):
                 if other == 12:
                     self.aList.remove(12)
                     self.aList.remove(13)
                     self.aList.remove(14)
-                return 1
+                return 0
 
         self.assert_(Deviant1() not in Deviant1.aList)
 
-        class Deviant2:
-            """Behaves strangely when compared
-
-            This class raises an exception during comparison.  That in
-            turn causes the comparison to fail with a TypeError.
-            """
-            def __lt__(self, other):
-                if other == 4:
-                    raise RuntimeError("gotcha")
-
-        try:
-            self.assert_(Deviant2() not in a)
-        except TypeError:
-            pass
-
     def test_nonreflexive(self):
         # containment and equality tests involving elements that are
         # not necessarily equal to themselves

Modified: python/branches/py3k-issue1717/Lib/test/test_copy.py
==============================================================================
--- python/branches/py3k-issue1717/Lib/test/test_copy.py	(original)
+++ python/branches/py3k-issue1717/Lib/test/test_copy.py	Tue Jan 27 21:24:52 2009
@@ -2,10 +2,13 @@
 
 import copy
 import copyreg
-
+from operator import le, lt, ge, gt, eq, ne
 import unittest
 from test import support
-from test.support import fcmp
+
+order_comparisons = le, lt, ge, gt
+equality_comparisons = eq, ne
+comparisons = order_comparisons + equality_comparisons
 
 class TestCopy(unittest.TestCase):
 
@@ -272,7 +275,8 @@
         x = []
         x.append(x)
         y = copy.deepcopy(x)
-        self.assertRaises(RuntimeError, fcmp, y, x)
+        for op in comparisons:
+            self.assertRaises(RuntimeError, op, y, x)
         self.assert_(y is not x)
         self.assert_(y[0] is y)
         self.assertEqual(len(y), 1)
@@ -288,7 +292,8 @@
         x = ([],)
         x[0].append(x)
         y = copy.deepcopy(x)
-        self.assertRaises(RuntimeError, fcmp, y, x)
+        for op in comparisons:
+            self.assertRaises(RuntimeError, op, y, x)
         self.assert_(y is not x)
         self.assert_(y[0] is not x[0])
         self.assert_(y[0][0] is y)
@@ -304,7 +309,10 @@
         x = {}
         x['foo'] = x
         y = copy.deepcopy(x)
-        self.assertRaises(TypeError, fcmp, y, x)
+        for op in order_comparisons:
+            self.assertRaises(TypeError, op, y, x)
+        for op in equality_comparisons:
+            self.assertRaises(RuntimeError, op, y, x)
         self.assert_(y is not x)
         self.assert_(y['foo'] is y)
         self.assertEqual(len(y), 1)

Modified: python/branches/py3k-issue1717/Lib/test/test_datetime.py
==============================================================================
--- python/branches/py3k-issue1717/Lib/test/test_datetime.py	(original)
+++ python/branches/py3k-issue1717/Lib/test/test_datetime.py	Tue Jan 27 21:24:52 2009
@@ -7,8 +7,9 @@
 import pickle
 import unittest
 
+from operator import lt, le, gt, ge, eq, ne
+
 from test import support
-from test.support import fcmp
 
 from datetime import MINYEAR, MAXYEAR
 from datetime import timedelta
@@ -2098,9 +2099,10 @@
         d2 = base.replace(minute=11)
         for x in d0, d1, d2:
             for y in d0, d1, d2:
-                got = fcmp(x, y)
-                expected = fcmp(x.minute, y.minute)
-                self.assertEqual(got, expected)
+                for op in lt, le, gt, ge, eq, ne:
+                    got = op(x, y)
+                    expected = op(x.minute, y.minute)
+                    self.assertEqual(got, expected)
 
         # However, if they're different members, uctoffset is not ignored.
         # Note that a time can't actually have an operand-depedent offset,
@@ -2112,7 +2114,7 @@
             d2 = base.replace(minute=11, tzinfo=OperandDependentOffset())
             for x in d0, d1, d2:
                 for y in d0, d1, d2:
-                    got = fcmp(x, y)
+                    got = (x > y) - (x < y)
                     if (x is d0 or x is d1) and (y is d0 or y is d1):
                         expected = 0
                     elif x is y is d2:

Modified: python/branches/py3k-issue1717/Lib/test/test_itertools.py
==============================================================================
--- python/branches/py3k-issue1717/Lib/test/test_itertools.py	(original)
+++ python/branches/py3k-issue1717/Lib/test/test_itertools.py	Tue Jan 27 21:24:52 2009
@@ -110,6 +110,14 @@
                 if sorted(indices) == list(indices):
                     yield tuple(pool[i] for i in indices)
 
+        def combinations3(iterable, r):
+            'Pure python version from cwr()'
+            pool = tuple(iterable)
+            n = len(pool)
+            for indices in combinations_with_replacement(range(n), r):
+                if len(set(indices)) == r:
+                    yield tuple(pool[i] for i in indices)
+
         for n in range(7):
             values = [5*x-12 for x in range(n)]
             for r in range(n+2):
@@ -126,11 +134,82 @@
                                      [e for e in values if e in c])      # comb is a subsequence of the input iterable
                 self.assertEqual(result, list(combinations1(values, r))) # matches first pure python version
                 self.assertEqual(result, list(combinations2(values, r))) # matches second pure python version
+                self.assertEqual(result, list(combinations3(values, r))) # matches second pure python version
 
         # Test implementation detail:  tuple re-use
         self.assertEqual(len(set(map(id, combinations('abcde', 3)))), 1)
         self.assertNotEqual(len(set(map(id, list(combinations('abcde', 3))))), 1)
 
+    def test_combinations_with_replacement(self):
+        cwr = combinations_with_replacement
+        self.assertRaises(TypeError, cwr, 'abc')       # missing r argument
+        self.assertRaises(TypeError, cwr, 'abc', 2, 1) # too many arguments
+        self.assertRaises(TypeError, cwr, None)        # pool is not iterable
+        self.assertRaises(ValueError, cwr, 'abc', -2)  # r is negative
+        self.assertEqual(list(cwr('ABC', 2)),
+                         [('A','A'), ('A','B'), ('A','C'), ('B','B'), ('B','C'), ('C','C')])
+
+        def cwr1(iterable, r):
+            'Pure python version shown in the docs'
+            # number items returned:  (n+r-1)! / r! / (n-1)! when n>0
+            pool = tuple(iterable)
+            n = len(pool)
+            if not n and r:
+                return
+            indices = [0] * r
+            yield tuple(pool[i] for i in indices)
+            while 1:
+                for i in reversed(range(r)):
+                    if indices[i] != n - 1:
+                        break
+                else:
+                    return
+                indices[i:] = [indices[i] + 1] * (r - i)
+                yield tuple(pool[i] for i in indices)
+
+        def cwr2(iterable, r):
+            'Pure python version shown in the docs'
+            pool = tuple(iterable)
+            n = len(pool)
+            for indices in product(range(n), repeat=r):
+                if sorted(indices) == list(indices):
+                    yield tuple(pool[i] for i in indices)
+
+        def numcombs(n, r):
+            if not n:
+                return 0 if r else 1
+            return fact(n+r-1) / fact(r)/ fact(n-1)
+
+        for n in range(7):
+            values = [5*x-12 for x in range(n)]
+            for r in range(n+2):
+                result = list(cwr(values, r))
+
+                self.assertEqual(len(result), numcombs(n, r))           # right number of combs
+                self.assertEqual(len(result), len(set(result)))         # no repeats
+                self.assertEqual(result, sorted(result))                # lexicographic order
+
+                regular_combs = list(combinations(values, r))           # compare to combs without replacement
+                if n == 0 or r <= 1:
+                    self.assertEquals(result, regular_combs)            # cases that should be identical
+                else:
+                    self.assert_(set(result) >= set(regular_combs))     # rest should be supersets of regular combs
+
+                for c in result:
+                    self.assertEqual(len(c), r)                         # r-length combinations
+                    noruns = [k for k,v in groupby(c)]                  # combo without consecutive repeats
+                    self.assertEqual(len(noruns), len(set(noruns)))     # no repeats other than consecutive
+                    self.assertEqual(list(c), sorted(c))                # keep original ordering
+                    self.assert_(all(e in values for e in c))           # elements taken from input iterable
+                    self.assertEqual(noruns,
+                                     [e for e in values if e in c])     # comb is a subsequence of the input iterable
+                self.assertEqual(result, list(cwr1(values, r)))         # matches first pure python version
+                self.assertEqual(result, list(cwr2(values, r)))         # matches second pure python version
+
+        # Test implementation detail:  tuple re-use
+        self.assertEqual(len(set(map(id, cwr('abcde', 3)))), 1)
+        self.assertNotEqual(len(set(map(id, list(cwr('abcde', 3))))), 1)
+
     def test_permutations(self):
         self.assertRaises(TypeError, permutations)              # too few arguments
         self.assertRaises(TypeError, permutations, 'abc', 2, 1) # too many arguments
@@ -195,6 +274,54 @@
         self.assertEqual(len(set(map(id, permutations('abcde', 3)))), 1)
         self.assertNotEqual(len(set(map(id, list(permutations('abcde', 3))))), 1)
 
+    def test_combinatorics(self):
+        # Test relationships between product(), permutations(),
+        # combinations() and combinations_with_replacement().
+
+        for n in range(6):
+            s = 'ABCDEFG'[:n]
+            for r in range(8):
+                prod = list(product(s, repeat=r))
+                cwr = list(combinations_with_replacement(s, r))
+                perm = list(permutations(s, r))
+                comb = list(combinations(s, r))
+
+                # Check size
+                self.assertEquals(len(prod), n**r)
+                self.assertEquals(len(cwr), (fact(n+r-1) / fact(r)/ fact(n-1)) if n else (not r))
+                self.assertEquals(len(perm), 0 if r>n else fact(n) / fact(n-r))
+                self.assertEquals(len(comb), 0 if r>n else fact(n) / fact(r) / fact(n-r))
+
+                # Check lexicographic order without repeated tuples
+                self.assertEquals(prod, sorted(set(prod)))
+                self.assertEquals(cwr, sorted(set(cwr)))
+                self.assertEquals(perm, sorted(set(perm)))
+                self.assertEquals(comb, sorted(set(comb)))
+
+                # Check interrelationships
+                self.assertEquals(cwr, [t for t in prod if sorted(t)==list(t)]) # cwr: prods which are sorted
+                self.assertEquals(perm, [t for t in prod if len(set(t))==r])    # perm: prods with no dups
+                self.assertEqual(comb, [t for t in perm if sorted(t)==list(t)]) # comb: perms that are sorted
+                self.assertEqual(comb, [t for t in cwr if len(set(t))==r])      # comb: cwrs without dups
+                self.assertEqual(comb, list(filter(set(cwr).__contains__, perm)))     # comb: perm that is a cwr
+                self.assertEqual(comb, list(filter(set(perm).__contains__, cwr)))     # comb: cwr that is a perm
+                self.assertEqual(comb, sorted(set(cwr) & set(perm)))            # comb: both a cwr and a perm
+
+    def test_compress(self):
+        self.assertEqual(list(compress('ABCDEF', [1,0,1,0,1,1])), list('ACEF'))
+        self.assertEqual(list(compress('ABCDEF', [0,0,0,0,0,0])), list(''))
+        self.assertEqual(list(compress('ABCDEF', [1,1,1,1,1,1])), list('ABCDEF'))
+        self.assertEqual(list(compress('ABCDEF', [1,0,1])), list('AC'))
+        self.assertEqual(list(compress('ABC', [0,1,1,1,1,1])), list('BC'))
+        n = 10000
+        data = chain.from_iterable(repeat(range(6), n))
+        selectors = chain.from_iterable(repeat((0, 1)))
+        self.assertEqual(list(compress(data, selectors)), [1,3,5] * n)
+        self.assertRaises(TypeError, compress, None, range(6))      # 1st arg not iterable
+        self.assertRaises(TypeError, compress, range(6), None)      # 2nd arg not iterable
+        self.assertRaises(TypeError, compress, range(6))            # too few args
+        self.assertRaises(TypeError, compress, range(6), None)      # too many args
+
     def test_count(self):
         self.assertEqual(lzip('abc',count()), [('a', 0), ('b', 1), ('c', 2)])
         self.assertEqual(lzip('abc',count(3)), [('a', 3), ('b', 4), ('c', 5)])
@@ -715,6 +842,13 @@
         self.assertEqual(list(combinations(range(4), 3)),
                          [(0,1,2), (0,1,3), (0,2,3), (1,2,3)])
 
+    def test_combinations_with_replacement(self):
+        self.assertEqual(list(combinations_with_replacement('ABC', 2)),
+                         [('A','A'), ('A','B'), ('A','C'), ('B','B'), ('B','C'), ('C','C')])
+
+    def test_compress(self):
+        self.assertEqual(list(compress('ABCDEF', [1,0,1,0,1,1])), list('ACEF'))
+
     def test_count(self):
         self.assertEqual(list(islice(count(10), 5)), [10, 11, 12, 13, 14])
 
@@ -795,6 +929,14 @@
         a = []
         self.makecycle(combinations([1,2,a,3], 3), a)
 
+    def test_combinations_with_replacement(self):
+        a = []
+        self.makecycle(combinations_with_replacement([1,2,a,3], 3), a)
+
+    def test_compress(self):
+        a = []
+        self.makecycle(compress('ABCDEF', [1,0,1,0,1,0]), a)
+
     def test_cycle(self):
         a = []
         self.makecycle(cycle([a]*2), a)
@@ -948,6 +1090,15 @@
             self.assertRaises(TypeError, list, chain(N(s)))
             self.assertRaises(ZeroDivisionError, list, chain(E(s)))
 
+    def test_compress(self):
+        for s in ("123", "", range(1000), ('do', 1.2), range(2000,2200,5)):
+            n = len(s)
+            for g in (G, I, Ig, S, L, R):
+                self.assertEqual(list(compress(g(s), repeat(1))), list(g(s)))
+            self.assertRaises(TypeError, compress, X(s), repeat(1))
+            self.assertRaises(TypeError, compress, N(s), repeat(1))
+            self.assertRaises(ZeroDivisionError, list, compress(E(s), repeat(1)))
+
     def test_product(self):
         for s in ("123", "", range(1000), ('do', 1.2), range(2000,2200,5)):
             self.assertRaises(TypeError, product, X(s))
@@ -1144,7 +1295,7 @@
     def test_keywords_in_subclass(self):
         # count is not subclassable...
         for cls in (repeat, zip, filter, filterfalse, chain, map,
-                    starmap, islice, takewhile, dropwhile, cycle):
+                    starmap, islice, takewhile, dropwhile, cycle, compress):
             class Subclass(cls):
                 def __init__(self, newarg=None, *args):
                     cls.__init__(self, *args)
@@ -1261,7 +1412,7 @@
 >>> def grouper(n, iterable, fillvalue=None):
 ...     "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx"
 ...     args = [iter(iterable)] * n
-...     return zip_longest(fillvalue=fillvalue, *args)
+...     return zip_longest(*args, fillvalue=fillvalue)
 
 >>> def roundrobin(*iterables):
 ...     "roundrobin('ABC', 'D', 'EF') --> A D E B F C"
@@ -1277,30 +1428,9 @@
 ...             nexts = cycle(islice(nexts, pending))
 
 >>> def powerset(iterable):
-...     "powerset('ab') --> set([]), set(['a']), set(['b']), set(['a', 'b'])"
-...     # Recipe credited to Eric Raymond
-...     pairs = [(2**i, x) for i, x in enumerate(iterable)]
-...     for n in range(2**len(pairs)):
-...         yield set(x for m, x in pairs if m&n)
-
->>> def compress(data, selectors):
-...     "compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F"
-...     return (d for d, s in zip(data, selectors) if s)
-
->>> def combinations_with_replacement(iterable, r):
-...     "combinations_with_replacement('ABC', 3) --> AA AB AC BB BC CC"
-...     pool = tuple(iterable)
-...     n = len(pool)
-...     indices = [0] * r
-...     yield tuple(pool[i] for i in indices)
-...     while 1:
-...         for i in reversed(range(r)):
-...             if indices[i] != n - 1:
-...                 break
-...         else:
-...             return
-...         indices[i:] = [indices[i] + 1] * (r - i)
-...         yield tuple(pool[i] for i in indices)
+...     "powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)"
+...     s = list(iterable)
+...     return chain.from_iterable(combinations(s, r) for r in range(len(s)+1))
 
 >>> def unique_everseen(iterable, key=None):
 ...     "List unique elements, preserving order. Remember all elements ever seen."
@@ -1379,33 +1509,13 @@
 >>> list(roundrobin('abc', 'd', 'ef'))
 ['a', 'd', 'e', 'b', 'f', 'c']
 
->>> list(map(sorted, powerset('ab')))
-[[], ['a'], ['b'], ['a', 'b']]
-
->>> list(compress('abcdef', [1,0,1,0,1,1]))
-['a', 'c', 'e', 'f']
-
->>> list(combinations_with_replacement('abc', 2))
-[('a', 'a'), ('a', 'b'), ('a', 'c'), ('b', 'b'), ('b', 'c'), ('c', 'c')]
-
->>> list(combinations_with_replacement('01', 3))
-[('0', '0', '0'), ('0', '0', '1'), ('0', '1', '1'), ('1', '1', '1')]
-
->>> def combinations_with_replacement2(iterable, r):
-...     'Alternate version that filters from product()'
-...     pool = tuple(iterable)
-...     n = len(pool)
-...     for indices in product(range(n), repeat=r):
-...         if sorted(indices) == list(indices):
-...             yield tuple(pool[i] for i in indices)
-
->>> list(combinations_with_replacement('abc', 2)) == list(combinations_with_replacement2('abc', 2))
-True
+>>> list(powerset([1,2,3]))
+[(), (1,), (2,), (3,), (1, 2), (1, 3), (2, 3), (1, 2, 3)]
 
->>> list(combinations_with_replacement('01', 3)) == list(combinations_with_replacement2('01', 3))
+>>> all(len(list(powerset(range(n)))) == 2**n for n in range(18))
 True
 
->>> list(combinations_with_replacement('2310', 6)) == list(combinations_with_replacement2('2310', 6))
+>>> list(powerset('abcde')) == sorted(sorted(set(powerset('abcde'))), key=len)
 True
 
 >>> list(unique_everseen('AAAABBBCCDAABBB'))

Modified: python/branches/py3k-issue1717/Lib/test/test_operator.py
==============================================================================
--- python/branches/py3k-issue1717/Lib/test/test_operator.py	(original)
+++ python/branches/py3k-issue1717/Lib/test/test_operator.py	Tue Jan 27 21:24:52 2009
@@ -164,31 +164,6 @@
         self.failUnlessRaises(TypeError, operator.invert, None)
         self.assertEqual(operator.inv(4), -5)
 
-    def test_isMappingType(self):
-        self.failUnlessRaises(TypeError, operator.isMappingType)
-        self.failIf(operator.isMappingType(1))
-        self.failIf(operator.isMappingType(operator.isMappingType))
-        self.failUnless(operator.isMappingType(operator.__dict__))
-        self.failUnless(operator.isMappingType({}))
-
-    def test_isNumberType(self):
-        self.failUnlessRaises(TypeError, operator.isNumberType)
-        self.failUnless(operator.isNumberType(8))
-        self.failUnless(operator.isNumberType(8j))
-        self.failUnless(operator.isNumberType(8))
-        self.failUnless(operator.isNumberType(8.3))
-        self.failIf(operator.isNumberType(dir()))
-
-    def test_isSequenceType(self):
-        self.failUnlessRaises(TypeError, operator.isSequenceType)
-        self.failUnless(operator.isSequenceType(dir()))
-        self.failUnless(operator.isSequenceType(()))
-        self.failUnless(operator.isSequenceType(range(10)))
-        self.failUnless(operator.isSequenceType('yeahbuddy'))
-        self.failIf(operator.isSequenceType(3))
-        class Dict(dict): pass
-        self.failIf(operator.isSequenceType(Dict()))
-
     def test_lshift(self):
         self.failUnlessRaises(TypeError, operator.lshift)
         self.failUnlessRaises(TypeError, operator.lshift, None, 42)
@@ -235,31 +210,6 @@
         self.assertRaises(TypeError, operator.pow, 1)
         self.assertRaises(TypeError, operator.pow, 1, 2, 3)
 
-    def test_repeat(self):
-        a = list(range(3))
-        self.failUnlessRaises(TypeError, operator.repeat)
-        self.failUnlessRaises(TypeError, operator.repeat, a, None)
-        self.failUnless(operator.repeat(a, 2) == a+a)
-        self.failUnless(operator.repeat(a, 1) == a)
-        self.failUnless(operator.repeat(a, 0) == [])
-        a = (1, 2, 3)
-        self.failUnless(operator.repeat(a, 2) == a+a)
-        self.failUnless(operator.repeat(a, 1) == a)
-        self.failUnless(operator.repeat(a, 0) == ())
-        a = '123'
-        self.failUnless(operator.repeat(a, 2) == a+a)
-        self.failUnless(operator.repeat(a, 1) == a)
-        self.failUnless(operator.repeat(a, 0) == '')
-        a = Seq1([4, 5, 6])
-        self.failUnless(operator.repeat(a, 2) == [4, 5, 6, 4, 5, 6])
-        self.failUnless(operator.repeat(a, 1) == [4, 5, 6])
-        self.failUnless(operator.repeat(a, 0) == [])
-        a = Seq2([4, 5, 6])
-        self.failUnless(operator.repeat(a, 2) == [4, 5, 6, 4, 5, 6])
-        self.failUnless(operator.repeat(a, 1) == [4, 5, 6])
-        self.failUnless(operator.repeat(a, 0) == [])
-        self.failUnlessRaises(TypeError, operator.repeat, 6, 7)
-
     def test_rshift(self):
         self.failUnlessRaises(TypeError, operator.rshift)
         self.failUnlessRaises(TypeError, operator.rshift, None, 42)
@@ -443,7 +393,6 @@
         self.assertEqual(operator.itruediv (c, 5), "itruediv")
         self.assertEqual(operator.ixor     (c, 5), "ixor")
         self.assertEqual(operator.iconcat  (c, c), "iadd")
-        self.assertEqual(operator.irepeat  (c, 5), "imul")
         self.assertEqual(operator.__iadd__     (c, 5), "iadd")
         self.assertEqual(operator.__iand__     (c, 5), "iand")
         self.assertEqual(operator.__ifloordiv__(c, 5), "ifloordiv")
@@ -457,7 +406,6 @@
         self.assertEqual(operator.__itruediv__ (c, 5), "itruediv")
         self.assertEqual(operator.__ixor__     (c, 5), "ixor")
         self.assertEqual(operator.__iconcat__  (c, c), "iadd")
-        self.assertEqual(operator.__irepeat__  (c, 5), "imul")
 
 def test_main(verbose=None):
     import sys

Modified: python/branches/py3k-issue1717/Lib/test/test_sundry.py
==============================================================================
--- python/branches/py3k-issue1717/Lib/test/test_sundry.py	(original)
+++ python/branches/py3k-issue1717/Lib/test/test_sundry.py	Tue Jan 27 21:24:52 2009
@@ -21,7 +21,6 @@
             import distutils.filelist
             if sys.platform.startswith('win'):
                 import distutils.msvccompiler
-            import distutils.mwerkscompiler
             import distutils.text_file
             import distutils.unixccompiler
 

Modified: python/branches/py3k-issue1717/Lib/test/test_uuid.py
==============================================================================
--- python/branches/py3k-issue1717/Lib/test/test_uuid.py	(original)
+++ python/branches/py3k-issue1717/Lib/test/test_uuid.py	Tue Jan 27 21:24:52 2009
@@ -1,6 +1,5 @@
 from unittest import TestCase
 from test import support
-from test.support import fcmp
 import uuid
 
 def importable(name):
@@ -182,7 +181,12 @@
         # Test comparison of UUIDs.
         for i in range(len(ascending)):
             for j in range(len(ascending)):
-                equal(fcmp(i, j), fcmp(ascending[i], ascending[j]))
+                equal(i < j, ascending[i] < ascending[j])
+                equal(i <= j, ascending[i] <= ascending[j])
+                equal(i == j, ascending[i] == ascending[j])
+                equal(i > j, ascending[i] > ascending[j])
+                equal(i >= j, ascending[i] >= ascending[j])
+                equal(i != j, ascending[i] != ascending[j])
 
         # Test sorting of UUIDs (above list is in ascending order).
         resorted = ascending[:]

Modified: python/branches/py3k-issue1717/Lib/unittest.py
==============================================================================
--- python/branches/py3k-issue1717/Lib/unittest.py	(original)
+++ python/branches/py3k-issue1717/Lib/unittest.py	Tue Jan 27 21:24:52 2009
@@ -539,7 +539,8 @@
             return mycmp(self.obj, other.obj) == -1
     return K
 
-def cmp(x, y):
+def three_way_cmp(x, y):
+    """Return -1 if x < y, 0 if x == y and 1 if x > y"""
     return (x > y) - (x < y)
 
 class TestLoader(object):
@@ -547,7 +548,7 @@
     criteria and returning them wrapped in a TestSuite
     """
     testMethodPrefix = 'test'
-    sortTestMethodsUsing = staticmethod(cmp)
+    sortTestMethodsUsing = staticmethod(three_way_cmp)
     suiteClass = TestSuite
 
     def loadTestsFromTestCase(self, testCaseClass):
@@ -655,14 +656,18 @@
     if suiteClass: loader.suiteClass = suiteClass
     return loader
 
-def getTestCaseNames(testCaseClass, prefix, sortUsing=cmp):
+def getTestCaseNames(testCaseClass, prefix, sortUsing=three_way_cmp):
     return _makeLoader(prefix, sortUsing).getTestCaseNames(testCaseClass)
 
-def makeSuite(testCaseClass, prefix='test', sortUsing=cmp, suiteClass=TestSuite):
-    return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromTestCase(testCaseClass)
-
-def findTestCases(module, prefix='test', sortUsing=cmp, suiteClass=TestSuite):
-    return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromModule(module)
+def makeSuite(testCaseClass, prefix='test', sortUsing=three_way_cmp,
+              suiteClass=TestSuite):
+    return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromTestCase(
+        testCaseClass)
+
+def findTestCases(module, prefix='test', sortUsing=three_way_cmp,
+                  suiteClass=TestSuite):
+    return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromModule(
+        module)
 
 
 ##############################################################################

Modified: python/branches/py3k-issue1717/Lib/xml/dom/minidom.py
==============================================================================
--- python/branches/py3k-issue1717/Lib/xml/dom/minidom.py	(original)
+++ python/branches/py3k-issue1717/Lib/xml/dom/minidom.py	Tue Jan 27 21:24:52 2009
@@ -520,12 +520,30 @@
 
     __len__ = _get_length
 
-    def __cmp__(self, other):
+    def _cmp(self, other):
         if self._attrs is getattr(other, "_attrs", None):
             return 0
         else:
             return (id(self) > id(other)) - (id(self) < id(other))
 
+    def __eq__(self, other):
+        return self._cmp(other) == 0
+
+    def __ge__(self, other):
+        return self._cmp(other) >= 0
+
+    def __gt__(self, other):
+        return self._cmp(other) > 0
+
+    def __le__(self, other):
+        return self._cmp(other) <= 0
+
+    def __lt__(self, other):
+        return self._cmp(other) < 0
+
+    def __ne__(self, other):
+        return self._cmp(other) != 0
+
     def __getitem__(self, attname_or_tuple):
         if isinstance(attname_or_tuple, tuple):
             return self._attrsNS[attname_or_tuple]

Modified: python/branches/py3k-issue1717/Lib/xml/etree/ElementTree.py
==============================================================================
--- python/branches/py3k-issue1717/Lib/xml/etree/ElementTree.py	(original)
+++ python/branches/py3k-issue1717/Lib/xml/etree/ElementTree.py	Tue Jan 27 21:24:52 2009
@@ -498,10 +498,30 @@
         return self.text
     def __hash__(self):
         return hash(self.text)
-    def __cmp__(self, other):
+    def __le__(self, other):
         if isinstance(other, QName):
-            return (self.text > other.text) - (self.text < other.text)
-        return (self.text > other) - (self.text < other)
+            return self.text <= other.text
+        return self.text <= other
+    def __lt__(self, other):
+        if isinstance(other, QName):
+            return self.text < other.text
+        return self.text < other
+    def __ge__(self, other):
+        if isinstance(other, QName):
+            return self.text >= other.text
+        return self.text >= other
+    def __gt__(self, other):
+        if isinstance(other, QName):
+            return self.text > other.text
+        return self.text > other
+    def __eq__(self, other):
+        if isinstance(other, QName):
+            return self.text == other.text
+        return self.text == other
+    def __ne__(self, other):
+        if isinstance(other, QName):
+            return self.text != other.text
+        return self.text != other
 
 ##
 # ElementTree wrapper class.  This class represents an entire element

Modified: python/branches/py3k-issue1717/Misc/NEWS
==============================================================================
--- python/branches/py3k-issue1717/Misc/NEWS	(original)
+++ python/branches/py3k-issue1717/Misc/NEWS	Tue Jan 27 21:24:52 2009
@@ -144,6 +144,24 @@
 Library
 -------
 
+- Removed isSequenceType(), isMappingType, and isNumberType() from the
+  operator module; use the abstract base classes instead.  Also removed
+  the repeat() function; use mul() instead.
+
+- Issue 5021:  doctest.testfile() did not create __name__ and
+  collections.namedtuple() relied on __name__ being defined.
+
+- Backport importlib from Python 3.1. Only the import_module() function has
+  been backported to help facilitate transitions from 2.7 to 3.1.
+
+- Issue #1885: distutils. When running sdist with --formats=tar,gztar
+  the tar file was overriden by the gztar one.
+
+- Issue #4863: distutils.mwerkscompiler has been removed.
+
+- Added a new itertools functions:  combinations_with_replacement()
+  and compress().
+
 - Fix and properly document the multiprocessing module's logging
   support, expose the internal levels and provide proper usage
   examples.

Modified: python/branches/py3k-issue1717/Modules/_ssl.c
==============================================================================
--- python/branches/py3k-issue1717/Modules/_ssl.c	(original)
+++ python/branches/py3k-issue1717/Modules/_ssl.c	Tue Jan 27 21:24:52 2009
@@ -1592,7 +1592,7 @@
 		for (i = 0;  i < _ssl_locks_count;  i++) {
 			_ssl_locks[i] = PyThread_allocate_lock();
 			if (_ssl_locks[i] == NULL) {
-				int j;
+				unsigned int j;
 				for (j = 0;  j < i;  j++) {
 					PyThread_free_lock(_ssl_locks[j]);
 				}

Modified: python/branches/py3k-issue1717/Modules/itertoolsmodule.c
==============================================================================
--- python/branches/py3k-issue1717/Modules/itertoolsmodule.c	(original)
+++ python/branches/py3k-issue1717/Modules/itertoolsmodule.c	Tue Jan 27 21:24:52 2009
@@ -1683,7 +1683,8 @@
 	PyObject_GC_UnTrack(lz);
 	Py_XDECREF(lz->pools);
 	Py_XDECREF(lz->result);
-	PyMem_Free(lz->indices);
+	if (lz->indices != NULL)
+		PyMem_Free(lz->indices);
 	Py_TYPE(lz)->tp_free(lz);
 }
 
@@ -1911,7 +1912,8 @@
 	PyObject_GC_UnTrack(co);
 	Py_XDECREF(co->pool);
 	Py_XDECREF(co->result);
-	PyMem_Free(co->indices);
+	if (co->indices != NULL)
+		PyMem_Free(co->indices);
 	Py_TYPE(co)->tp_free(co);
 }
 
@@ -2060,6 +2062,252 @@
 };
 
 
+/* combinations with replacement object *******************************************/
+
+/* Equivalent to:
+
+		def combinations_with_replacement(iterable, r):
+			"combinations_with_replacement('ABC', 2) --> AA AB AC BB BC CC"
+			# number items returned:  (n+r-1)! / r! / (n-1)!
+			pool = tuple(iterable)
+			n = len(pool)
+			indices = [0] * r
+			yield tuple(pool[i] for i in indices)   
+			while 1:
+				for i in reversed(range(r)):
+					if indices[i] != n - 1:
+						break
+				else:
+					return
+				indices[i:] = [indices[i] + 1] * (r - i)
+				yield tuple(pool[i] for i in indices)
+
+		def combinations_with_replacement2(iterable, r):
+			'Alternate version that filters from product()'
+			pool = tuple(iterable)
+			n = len(pool)
+			for indices in product(range(n), repeat=r):
+				if sorted(indices) == list(indices):
+					yield tuple(pool[i] for i in indices)
+*/
+typedef struct {
+	PyObject_HEAD
+	PyObject *pool;			/* input converted to a tuple */
+	Py_ssize_t *indices;    /* one index per result element */
+	PyObject *result;       /* most recently returned result tuple */
+	Py_ssize_t r;			/* size of result tuple */
+	int stopped;			/* set to 1 when the cwr iterator is exhausted */
+} cwrobject;
+
+static PyTypeObject cwr_type;
+
+static PyObject *
+cwr_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	cwrobject *co;
+	Py_ssize_t n;
+	Py_ssize_t r;
+	PyObject *pool = NULL;
+	PyObject *iterable = NULL;
+	Py_ssize_t *indices = NULL;
+	Py_ssize_t i;
+	static char *kwargs[] = {"iterable", "r", NULL};
+ 
+ 	if (!PyArg_ParseTupleAndKeywords(args, kwds, "On:combinations_with_replacement", kwargs, 
+					 &iterable, &r))
+		return NULL;
+
+	pool = PySequence_Tuple(iterable);
+	if (pool == NULL)
+		goto error;
+	n = PyTuple_GET_SIZE(pool);
+	if (r < 0) {
+		PyErr_SetString(PyExc_ValueError, "r must be non-negative");
+		goto error;
+	}
+
+	indices = PyMem_Malloc(r * sizeof(Py_ssize_t));
+	if (indices == NULL) {
+    		PyErr_NoMemory();
+		goto error;
+	}
+
+	for (i=0 ; i<r ; i++)
+		indices[i] = 0;
+
+	/* create cwrobject structure */
+	co = (cwrobject *)type->tp_alloc(type, 0);
+	if (co == NULL)
+		goto error;
+
+	co->pool = pool;
+	co->indices = indices;
+	co->result = NULL;
+	co->r = r;
+	co->stopped = !n && r;
+
+	return (PyObject *)co;
+
+error:
+	if (indices != NULL)
+		PyMem_Free(indices);
+	Py_XDECREF(pool);
+	return NULL;
+}
+
+static void
+cwr_dealloc(cwrobject *co)
+{
+	PyObject_GC_UnTrack(co);
+	Py_XDECREF(co->pool);
+	Py_XDECREF(co->result);
+	if (co->indices != NULL)
+		PyMem_Free(co->indices);
+	Py_TYPE(co)->tp_free(co);
+}
+
+static int
+cwr_traverse(cwrobject *co, visitproc visit, void *arg)
+{
+	Py_VISIT(co->pool);
+	Py_VISIT(co->result);
+	return 0;
+}
+
+static PyObject *
+cwr_next(cwrobject *co)
+{
+	PyObject *elem;
+	PyObject *oldelem;
+	PyObject *pool = co->pool;
+	Py_ssize_t *indices = co->indices;
+	PyObject *result = co->result;
+	Py_ssize_t n = PyTuple_GET_SIZE(pool);
+	Py_ssize_t r = co->r;
+	Py_ssize_t i, j, index;
+
+	if (co->stopped)
+		return NULL;
+
+	if (result == NULL) {
+                /* On the first pass, initialize result tuple using the indices */
+		result = PyTuple_New(r);
+		if (result == NULL)
+            		goto empty;
+		co->result = result;
+		for (i=0; i<r ; i++) {
+			index = indices[i];
+    			elem = PyTuple_GET_ITEM(pool, index);
+    			Py_INCREF(elem);
+    			PyTuple_SET_ITEM(result, i, elem);
+		}
+	} else {
+		/* Copy the previous result tuple or re-use it if available */
+		if (Py_REFCNT(result) > 1) {
+			PyObject *old_result = result;
+			result = PyTuple_New(r);
+			if (result == NULL)
+				goto empty;
+			co->result = result;
+			for (i=0; i<r ; i++) {
+				elem = PyTuple_GET_ITEM(old_result, i);
+    				Py_INCREF(elem);
+    				PyTuple_SET_ITEM(result, i, elem);
+			}
+			Py_DECREF(old_result);
+		}
+		/* Now, we've got the only copy so we can update it in-place CPython's
+		   empty tuple is a singleton and cached in PyTuple's freelist. */
+		assert(r == 0 || Py_REFCNT(result) == 1);
+
+        /* Scan indices right-to-left until finding one that is not
+         * at its maximum (n-1). */
+		for (i=r-1 ; i >= 0 && indices[i] == n-1; i--)
+			;
+
+		/* If i is negative, then the indices are all at
+           their maximum value and we're done. */
+		if (i < 0)
+			goto empty;
+
+		/* Increment the current index which we know is not at its
+           maximum.  Then set all to the right to the same value. */
+		indices[i]++;
+		for (j=i+1 ; j<r ; j++)
+			indices[j] = indices[j-1];
+
+		/* Update the result tuple for the new indices
+		   starting with i, the leftmost index that changed */
+		for ( ; i<r ; i++) {
+			index = indices[i];
+			elem = PyTuple_GET_ITEM(pool, index);
+			Py_INCREF(elem);
+			oldelem = PyTuple_GET_ITEM(result, i);
+			PyTuple_SET_ITEM(result, i, elem);
+			Py_DECREF(oldelem);
+		}
+	}
+
+	Py_INCREF(result);
+	return result;
+
+empty:
+	co->stopped = 1;
+	return NULL;
+}
+
+PyDoc_STRVAR(cwr_doc,
+"combinations_with_replacement(iterable[, r]) --> combinations_with_replacement object\n\
+\n\
+Return successive r-length combinations of elements in the iterable\n\
+allowing individual elements to have successive repeats.\n\
+combinations_with_replacement('ABC', 2) --> AA AB AC BB BC CC");
+
+static PyTypeObject cwr_type = {
+	PyVarObject_HEAD_INIT(NULL, 0)
+	"itertools.combinations_with_replacement",		/* tp_name */
+	sizeof(cwrobject),		/* tp_basicsize */
+	0,						/* tp_itemsize */
+	/* methods */
+	(destructor)cwr_dealloc,	/* tp_dealloc */
+	0,						/* tp_print */
+	0,						/* tp_getattr */
+	0,						/* tp_setattr */
+	0,						/* tp_compare */
+	0,						/* tp_repr */
+	0,						/* tp_as_number */
+	0,						/* tp_as_sequence */
+	0,						/* tp_as_mapping */
+	0,						/* tp_hash */
+	0,						/* tp_call */
+	0,						/* tp_str */
+	PyObject_GenericGetAttr,	/* tp_getattro */
+	0,						/* tp_setattro */
+	0,						/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+		Py_TPFLAGS_BASETYPE,	/* tp_flags */
+	cwr_doc,				/* tp_doc */
+	(traverseproc)cwr_traverse,	/* tp_traverse */
+	0,						/* tp_clear */
+	0,						/* tp_richcompare */
+	0,						/* tp_weaklistoffset */
+	PyObject_SelfIter,		/* tp_iter */
+	(iternextfunc)cwr_next,	/* tp_iternext */
+	0,						/* tp_methods */
+	0,						/* tp_members */
+	0,						/* tp_getset */
+	0,						/* tp_base */
+	0,						/* tp_dict */
+	0,						/* tp_descr_get */
+	0,						/* tp_descr_set */
+	0,						/* tp_dictoffset */
+	0,						/* tp_init */
+	0,						/* tp_alloc */
+	cwr_new,				/* tp_new */
+	PyObject_GC_Del,		/* tp_free */
+};
+
+
 /* permutations object ************************************************************
   
 def permutations(iterable, r=None):
@@ -2331,6 +2579,162 @@
 };
 
 
+/* compress object ************************************************************/
+
+/* Equivalent to:
+
+	def compress(data, selectors):
+		"compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F"
+		return (d for d, s in zip(data, selectors) if s)
+*/
+
+typedef struct {
+	PyObject_HEAD
+	PyObject *data;
+	PyObject *selectors;
+} compressobject;
+
+static PyTypeObject compress_type;
+
+static PyObject *
+compress_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	PyObject *seq1, *seq2;
+	PyObject *data=NULL, *selectors=NULL;
+	compressobject *lz;
+
+	if (type == &compress_type && !_PyArg_NoKeywords("compress()", kwds))
+		return NULL;
+
+	if (!PyArg_UnpackTuple(args, "compress", 2, 2, &seq1, &seq2))
+		return NULL;
+
+	data = PyObject_GetIter(seq1);
+	if (data == NULL)
+		goto fail;
+	selectors = PyObject_GetIter(seq2);
+	if (selectors == NULL)
+		goto fail;
+
+	/* create compressobject structure */
+	lz = (compressobject *)type->tp_alloc(type, 0);
+	if (lz == NULL)
+		goto fail;
+	lz->data = data;
+	lz->selectors = selectors;
+	return (PyObject *)lz;
+
+fail:
+	Py_XDECREF(data);
+	Py_XDECREF(selectors);
+	return NULL;
+}
+
+static void
+compress_dealloc(compressobject *lz)
+{
+	PyObject_GC_UnTrack(lz);
+	Py_XDECREF(lz->data);
+	Py_XDECREF(lz->selectors);
+	Py_TYPE(lz)->tp_free(lz);
+}
+
+static int
+compress_traverse(compressobject *lz, visitproc visit, void *arg)
+{
+	Py_VISIT(lz->data);
+	Py_VISIT(lz->selectors);
+	return 0;
+}
+
+static PyObject *
+compress_next(compressobject *lz)
+{
+	PyObject *data = lz->data, *selectors = lz->selectors;
+	PyObject *datum, *selector;
+	PyObject *(*datanext)(PyObject *) = *Py_TYPE(data)->tp_iternext;
+	PyObject *(*selectornext)(PyObject *) = *Py_TYPE(selectors)->tp_iternext;
+	int ok;
+
+	while (1) {
+		/* Steps:  get datum, get selector, evaluate selector.
+		   Order is important (to match the pure python version
+		   in terms of which input gets a chance to raise an
+		   exception first).
+		*/
+
+		datum = datanext(data);
+		if (datum == NULL)
+			return NULL;
+
+		selector = selectornext(selectors);
+		if (selector == NULL) {
+			Py_DECREF(datum);
+			return NULL;
+		}
+
+		ok = PyObject_IsTrue(selector);
+		Py_DECREF(selector);
+		if (ok == 1)
+			return datum;
+		Py_DECREF(datum);
+		if (ok == -1)
+			return NULL;
+	}
+}
+
+PyDoc_STRVAR(compress_doc,
+"compress(data sequence, selector sequence) --> iterator over selected data\n\
+\n\
+Return data elements corresponding to true selector elements.\n\
+Forms a shorter iterator from selected data elements using the\n\
+selectors to choose the data elements.");
+
+static PyTypeObject compress_type = {
+	PyVarObject_HEAD_INIT(NULL, 0)
+	"itertools.compress",		/* tp_name */
+	sizeof(compressobject),		/* tp_basicsize */
+	0,							/* tp_itemsize */
+	/* methods */
+	(destructor)compress_dealloc,	/* tp_dealloc */
+	0,								/* tp_print */
+	0,								/* tp_getattr */
+	0,								/* tp_setattr */
+	0,								/* tp_compare */
+	0,								/* tp_repr */
+	0,								/* tp_as_number */
+	0,								/* tp_as_sequence */
+	0,								/* tp_as_mapping */
+	0,								/* tp_hash */
+	0,								/* tp_call */
+	0,								/* tp_str */
+	PyObject_GenericGetAttr,		/* tp_getattro */
+	0,								/* tp_setattro */
+	0,								/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+		Py_TPFLAGS_BASETYPE,		/* tp_flags */
+	compress_doc,					/* tp_doc */
+	(traverseproc)compress_traverse,	/* tp_traverse */
+	0,								/* tp_clear */
+	0,								/* tp_richcompare */
+	0,								/* tp_weaklistoffset */
+	PyObject_SelfIter,				/* tp_iter */
+	(iternextfunc)compress_next,	/* tp_iternext */
+	0,								/* tp_methods */
+	0,								/* tp_members */
+	0,								/* tp_getset */
+	0,								/* tp_base */
+	0,								/* tp_dict */
+	0,								/* tp_descr_get */
+	0,								/* tp_descr_set */
+	0,								/* tp_dictoffset */
+	0,								/* tp_init */
+	0,								/* tp_alloc */
+	compress_new,					/* tp_new */
+	PyObject_GC_Del,				/* tp_free */
+};
+
+
 /* filterfalse object ************************************************************/
 
 typedef struct {
@@ -3035,12 +3439,14 @@
 	char *name;
 	PyTypeObject *typelist[] = {
 		&combinations_type,
+		&cwr_type,
 		&cycle_type,
 		&dropwhile_type,
 		&takewhile_type,
 		&islice_type,
 		&starmap_type,
 		&chain_type,
+		&compress_type,
 		&filterfalse_type,
 		&count_type,
 		&ziplongest_type,

Modified: python/branches/py3k-issue1717/Modules/operator.c
==============================================================================
--- python/branches/py3k-issue1717/Modules/operator.c	(original)
+++ python/branches/py3k-issue1717/Modules/operator.c	Tue Jan 27 21:24:52 2009
@@ -65,7 +65,6 @@
   if(! PyArg_UnpackTuple(a,#OP,2,2,&a1,&a2)) return NULL; \
   return PyObject_RichCompare(a1,a2,A); }
 
-spami(isNumberType     , PyNumber_Check)
 spami(truth            , PyObject_IsTrue)
 spam2(op_add           , PyNumber_Add)
 spam2(op_sub           , PyNumber_Subtract)
@@ -95,15 +94,11 @@
 spam2(op_iand          , PyNumber_InPlaceAnd)
 spam2(op_ixor          , PyNumber_InPlaceXor)
 spam2(op_ior           , PyNumber_InPlaceOr)
-spami(isSequenceType   , PySequence_Check)
 spam2(op_concat        , PySequence_Concat)
-spamoi(op_repeat       , PySequence_Repeat)
 spam2(op_iconcat       , PySequence_InPlaceConcat)
-spamoi(op_irepeat      , PySequence_InPlaceRepeat)
 spami2b(op_contains     , PySequence_Contains)
 spamn2(indexOf         , PySequence_Index)
 spamn2(countOf         , PySequence_Count)
-spami(isMappingType    , PyMapping_Check)
 spam2(op_getitem       , PyObject_GetItem)
 spam2n(op_delitem       , PyObject_DelItem)
 spam3n(op_setitem      , PyObject_SetItem)
@@ -173,10 +168,6 @@
 
 static struct PyMethodDef operator_methods[] = {
 
-spam1o(isNumberType,
- "isNumberType(a) -- Return True if a has a numeric type, False otherwise.")
-spam1o(isSequenceType,
- "isSequenceType(a) -- Return True if a has a sequence type, False otherwise.")
 spam1o(truth,
  "truth(a) -- Return True if a is true, False otherwise.")
 spam2(contains,__contains__,
@@ -185,8 +176,6 @@
  "indexOf(a, b) -- Return the first index of b in a.")
 spam1(countOf,
  "countOf(a, b) -- Return the number of times b occurs in a.")
-spam1o(isMappingType,
- "isMappingType(a) -- Return True if a has a mapping type, False otherwise.")
 
 spam1(is_, "is_(a, b) -- Same as a is b.")
 spam1(is_not, "is_not(a, b) -- Same as a is not b.")
@@ -221,12 +210,8 @@
 spam2(ior,__ior__, "ior(a, b) -- Same as a |= b.")
 spam2(concat,__concat__,
  "concat(a, b) -- Same as a + b, for a and b sequences.")
-spam2(repeat,__repeat__,
- "repeat(a, b) -- Return a * b, where a is a sequence, and b is an integer.")
 spam2(iconcat,__iconcat__,
  "iconcat(a, b) -- Same as a += b, for a and b sequences.")
-spam2(irepeat,__irepeat__,
- "irepeat(a, b) -- Same as a *= b, where a is a sequence, and b is an integer.")
 spam2(getitem,__getitem__,
  "getitem(a, b) -- Same as a[b].")
 spam2(setitem,__setitem__,

Modified: python/branches/py3k-issue1717/Objects/longobject.c
==============================================================================
--- python/branches/py3k-issue1717/Objects/longobject.c	(original)
+++ python/branches/py3k-issue1717/Objects/longobject.c	Tue Jan 27 21:24:52 2009
@@ -776,7 +776,7 @@
 	twodigits accum;	/* sliding register */
 	unsigned int accumbits; /* # bits in accum */
 	int do_twos_comp;	/* store 2's-comp?  is_signed and v < 0 */
-	twodigits carry;	/* for computing 2's-comp */
+	digit carry;		/* for computing 2's-comp */
 	size_t j;		/* # bytes filled */
 	unsigned char* p;	/* pointer to next byte in bytes */
 	int pincr;		/* direction to move p */
@@ -2274,7 +2274,7 @@
 static long
 long_hash(PyLongObject *v)
 {
-	long x;
+	unsigned long x;
 	Py_ssize_t i;
 	int sign;
 
@@ -2294,17 +2294,18 @@
 		i = -(i);
 	}
 #define LONG_BIT_PyLong_SHIFT	(8*sizeof(long) - PyLong_SHIFT)
-	/* The following loop produces a C long x such that (unsigned long)x
-	   is congruent to the absolute value of v modulo ULONG_MAX.  The
+	/* The following loop produces a C unsigned long x such that x is
+	   congruent to the absolute value of v modulo ULONG_MAX.  The
 	   resulting x is nonzero if and only if v is. */
 	while (--i >= 0) {
 		/* Force a native long #-bits (32 or 64) circular shift */
-		x = ((x << PyLong_SHIFT) & ~PyLong_MASK) | ((x >> LONG_BIT_PyLong_SHIFT) & PyLong_MASK);
+		x = ((x << PyLong_SHIFT) & ~PyLong_MASK) |
+			((x >> LONG_BIT_PyLong_SHIFT) & PyLong_MASK);
 		x += v->ob_digit[i];
-		/* If the addition above overflowed (thinking of x as
-		   unsigned), we compensate by incrementing.  This preserves
-		   the value modulo ULONG_MAX. */
-		if ((unsigned long)x < v->ob_digit[i])
+		/* If the addition above overflowed we compensate by
+		   incrementing.  This preserves the value modulo
+		   ULONG_MAX. */
+		if (x < v->ob_digit[i])
 			x++;
 	}
 #undef LONG_BIT_PyLong_SHIFT

Modified: python/branches/py3k-issue1717/Python/pythonrun.c
==============================================================================
--- python/branches/py3k-issue1717/Python/pythonrun.c	(original)
+++ python/branches/py3k-issue1717/Python/pythonrun.c	Tue Jan 27 21:24:52 2009
@@ -739,7 +739,12 @@
 	PyObject *line_buffering;
 	int buffering, isatty;
 
-	if (Py_UnbufferedStdioFlag)
+	/* stdin is always opened in buffered mode, first because it shouldn't
+	   make a difference in common use cases, second because TextIOWrapper
+	   depends on the presence of a read1() method which only exists on
+	   buffered streams.
+	*/
+	if (Py_UnbufferedStdioFlag && write_mode)
 		buffering = 0;
 	else
 		buffering = -1;
@@ -753,7 +758,7 @@
 	if (buf == NULL)
 		goto error;
 
-	if (!Py_UnbufferedStdioFlag) {
+	if (buffering) {
 		raw = PyObject_GetAttrString(buf, "raw");
 		if (raw == NULL)
 			goto error;


More information about the Python-checkins mailing list