Merged revisions 56020-56124 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/branches/p3yk

................
  r56037 | georg.brandl | 2007-06-19 05:33:20 -0700 (Tue, 19 Jun 2007) | 2 lines

  Patch #1739659: don't slice dict.keys() in pydoc.
................
  r56060 | martin.v.loewis | 2007-06-21 13:00:02 -0700 (Thu, 21 Jun 2007) | 2 lines

  Regenerate to add True, False, None.
................
  r56069 | neal.norwitz | 2007-06-21 22:31:56 -0700 (Thu, 21 Jun 2007) | 1 line

  Get the doctest working again after adding None, True, and False as kewyords.
................
  r56070 | neal.norwitz | 2007-06-21 23:25:33 -0700 (Thu, 21 Jun 2007) | 1 line

  Add space to error message.
................
  r56071 | neal.norwitz | 2007-06-21 23:40:04 -0700 (Thu, 21 Jun 2007) | 6 lines

  Get pybench working, primarily
   * Use print function
   * Stop using string module
   * Use sorted instead of assuming dict methods return lists
   * Convert range result to a list
................
  r56089 | collin.winter | 2007-06-26 10:31:48 -0700 (Tue, 26 Jun 2007) | 1 line

  Fix AttributeError in distutils/dir_util.py.
................
  r56124 | guido.van.rossum | 2007-06-29 18:04:31 -0700 (Fri, 29 Jun 2007) | 30 lines

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

  ........
    r56019 | lars.gustaebel | 2007-06-18 04:42:11 -0700 (Mon, 18 Jun 2007) | 2 lines

    Added exclude keyword argument to the TarFile.add() method.
  ........
    r56023 | lars.gustaebel | 2007-06-18 13:05:55 -0700 (Mon, 18 Jun 2007) | 3 lines

    Added missing \versionchanged tag for the new exclude
    parameter.
  ........
    r56038 | georg.brandl | 2007-06-19 05:36:00 -0700 (Tue, 19 Jun 2007) | 2 lines

    Bug #1737864: allow empty message in logging format routines.
  ........
    r56040 | georg.brandl | 2007-06-19 05:38:20 -0700 (Tue, 19 Jun 2007) | 2 lines

    Bug #1739115: make shutil.rmtree docs clear wrt. file deletion.
  ........
    r56084 | georg.brandl | 2007-06-25 08:21:23 -0700 (Mon, 25 Jun 2007) | 2 lines

    Bug #1742901: document None behavior of shlex.split.
  ........
    r56091 | georg.brandl | 2007-06-27 07:09:56 -0700 (Wed, 27 Jun 2007) | 2 lines

    Fix a variable name in winreg docs.
  ........
................
diff --git a/Lib/difflib.py b/Lib/difflib.py
index 601479c..f992650 100644
--- a/Lib/difflib.py
+++ b/Lib/difflib.py
@@ -719,7 +719,7 @@
     >>> import keyword as _keyword
     >>> get_close_matches("wheel", _keyword.kwlist)
     ['while']
-    >>> get_close_matches("apple", _keyword.kwlist)
+    >>> get_close_matches("Apple", _keyword.kwlist)
     []
     >>> get_close_matches("accept", _keyword.kwlist)
     ['except']
diff --git a/Lib/distutils/dir_util.py b/Lib/distutils/dir_util.py
index 0cfca2e..a6c4416 100644
--- a/Lib/distutils/dir_util.py
+++ b/Lib/distutils/dir_util.py
@@ -96,14 +96,12 @@
        for 'mkpath()'."""
 
     # First get the list of directories to create
-    need_dir = {}
+    need_dir = set()
     for file in files:
-        need_dir[os.path.join(base_dir, os.path.dirname(file))] = 1
-    need_dirs = need_dir.keys()
-    need_dirs.sort()
+        need_dir.add(os.path.join(base_dir, os.path.dirname(file)))
 
     # Now create them
-    for dir in need_dirs:
+    for dir in sorted(need_dir):
         mkpath(dir, mode, dry_run=dry_run)
 
 # create_tree ()
diff --git a/Lib/keyword.py b/Lib/keyword.py
index 3fa801d..9c49cd2 100755
--- a/Lib/keyword.py
+++ b/Lib/keyword.py
@@ -14,6 +14,9 @@
 
 kwlist = [
 #--start keywords--
+        'False',
+        'None',
+        'True',
         'and',
         'as',
         'assert',
diff --git a/Lib/logging/__init__.py b/Lib/logging/__init__.py
index 6dc5387..2c1e706 100644
--- a/Lib/logging/__init__.py
+++ b/Lib/logging/__init__.py
@@ -400,7 +400,7 @@
         traceback.print_exception(ei[0], ei[1], ei[2], None, sio)
         s = sio.getvalue()
         sio.close()
-        if s[-1] == "\n":
+        if s[-1:] == "\n":
             s = s[:-1]
         return s
 
@@ -427,7 +427,7 @@
             if not record.exc_text:
                 record.exc_text = self.formatException(record.exc_info)
         if record.exc_text:
-            if s[-1] != "\n":
+            if s[-1:] != "\n":
                 s = s + "\n"
             s = s + record.exc_text
         return s
diff --git a/Lib/pydoc.py b/Lib/pydoc.py
index e4074dc..4594333 100755
--- a/Lib/pydoc.py
+++ b/Lib/pydoc.py
@@ -1748,17 +1748,16 @@
 ''' % sys.version[:3])
 
     def list(self, items, columns=4, width=80):
-        items = items[:]
-        items.sort()
-        colw = width / columns
-        rows = (len(items) + columns - 1) / columns
+        items = list(sorted(items))
+        colw = width // columns
+        rows = (len(items) + columns - 1) // columns
         for row in range(rows):
             for col in range(columns):
                 i = col * rows + row
                 if i < len(items):
                     self.output.write(items[i])
                     if col < columns - 1:
-                        self.output.write(' ' + ' ' * (colw-1 - len(items[i])))
+                        self.output.write(' ' + ' ' * (colw - 1 - len(items[i])))
             self.output.write('\n')
 
     def listkeywords(self):
diff --git a/Lib/tarfile.py b/Lib/tarfile.py
index 94dac98..92daa5a 100644
--- a/Lib/tarfile.py
+++ b/Lib/tarfile.py
@@ -1925,18 +1925,24 @@
                     print("link to", tarinfo.linkname, end=' ')
             print()
 
-    def add(self, name, arcname=None, recursive=True):
+    def add(self, name, arcname=None, recursive=True, exclude=None):
         """Add the file `name' to the archive. `name' may be any type of file
            (directory, fifo, symbolic link, etc.). If given, `arcname'
            specifies an alternative name for the file in the archive.
            Directories are added recursively by default. This can be avoided by
-           setting `recursive' to False.
+           setting `recursive' to False. `exclude' is a function that should
+           return True for each filename to be excluded.
         """
         self._check("aw")
 
         if arcname is None:
             arcname = name
 
+        # Exclude pathnames.
+        if exclude is not None and exclude(name):
+            self._dbg(2, "tarfile: Excluded %r" % name)
+            return
+
         # Skip if somebody tries to archive the archive...
         if self.name is not None and os.path.abspath(name) == self.name:
             self._dbg(2, "tarfile: Skipped %r" % name)
@@ -1949,7 +1955,7 @@
                 if arcname == ".":
                     arcname = ""
                 for f in os.listdir(name):
-                    self.add(f, os.path.join(arcname, f))
+                    self.add(f, os.path.join(arcname, f), recursive, exclude)
             return
 
         self._dbg(1, name)
@@ -1971,7 +1977,7 @@
             self.addfile(tarinfo)
             if recursive:
                 for f in os.listdir(name):
-                    self.add(os.path.join(name, f), os.path.join(arcname, f))
+                    self.add(os.path.join(name, f), os.path.join(arcname, f), recursive, exclude)
 
         else:
             self.addfile(tarinfo)
diff --git a/Lib/test/test_tarfile.py b/Lib/test/test_tarfile.py
index 50c5bbe..1bfe9dcd 100644
--- a/Lib/test/test_tarfile.py
+++ b/Lib/test/test_tarfile.py
@@ -558,6 +558,27 @@
         os.chdir(cwd)
         self.assert_(tar.getnames() == [], "added the archive to itself")
 
+    def test_exclude(self):
+        tempdir = os.path.join(TEMPDIR, "exclude")
+        os.mkdir(tempdir)
+        try:
+            for name in ("foo", "bar", "baz"):
+                name = os.path.join(tempdir, name)
+                open(name, "wb").close()
+
+            def exclude(name):
+                return os.path.isfile(name)
+
+            tar = tarfile.open(tmpname, self.mode, encoding="iso8859-1")
+            tar.add(tempdir, arcname="empty_dir", exclude=exclude)
+            tar.close()
+
+            tar = tarfile.open(tmpname, "r")
+            self.assertEqual(len(tar.getmembers()), 1)
+            self.assertEqual(tar.getnames()[0], "empty_dir")
+        finally:
+            shutil.rmtree(tempdir)
+
 
 class StreamWriteTest(unittest.TestCase):