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

........
  r58822 | brett.cannon | 2007-11-02 23:47:02 -0700 (Fri, 02 Nov 2007) | 2 lines

  Add a missing quotation mark.
........
  r58840 | skip.montanaro | 2007-11-04 07:56:52 -0800 (Sun, 04 Nov 2007) | 2 lines

  Note change to get_dialect semantics in 2.5.  Will backport to 2.5.
........
  r58844 | georg.brandl | 2007-11-04 09:43:49 -0800 (Sun, 04 Nov 2007) | 2 lines

  Fix syntax for versionchanged markup.
........
  r58850 | gregory.p.smith | 2007-11-04 18:32:26 -0800 (Sun, 04 Nov 2007) | 9 lines

  Fixes bug 477182 on pybsddb.sf.net.  DB objects now load the flags and
  pay attention to them when opening an existing database.  This means
  that d[] behaves properly even on databases previously created with DB_DUP
  or DB_DUPSORT flags to allow duplicate keys.

  http://sourceforge.net/tracker/index.php?func=detail&aid=477182&group_id=13900&atid=113900

  Do not backport, this bugfix could be considered an API change.
........
  r58851 | gregory.p.smith | 2007-11-04 18:56:31 -0800 (Sun, 04 Nov 2007) | 3 lines

  Add the bsddb.db.DBEnv.lock_id_free method.
  Improve test_lock's tempdir creation and cleanup.
........
  r58852 | gregory.p.smith | 2007-11-05 01:06:28 -0800 (Mon, 05 Nov 2007) | 3 lines

   * db->get_types is only available in BerkeleyDB >= 4.2
   * get compiling with older versions of python again for a stand alone release.
........
  r58853 | gregory.p.smith | 2007-11-05 01:07:40 -0800 (Mon, 05 Nov 2007) | 2 lines

  * db->get_flags is only available in BerkeleyDB >= 4.2
........
  r58854 | mark.summerfield | 2007-11-05 01:22:48 -0800 (Mon, 05 Nov 2007) | 3 lines

  Added cross-references between the various archive file formats.
........
  r58857 | mark.summerfield | 2007-11-05 06:38:50 -0800 (Mon, 05 Nov 2007) | 5 lines

  Clarified the fact that you can have comments for individual archive
  members even though comments to the archive itself aren't currently
  supported.
........
diff --git a/Doc/library/bz2.rst b/Doc/library/bz2.rst
index 73fd450..ff3c773 100644
--- a/Doc/library/bz2.rst
+++ b/Doc/library/bz2.rst
@@ -12,7 +12,10 @@
 It implements a complete file interface, one-shot (de)compression functions, and
 types for sequential (de)compression.
 
-Here is a resume of the features offered by the bz2 module:
+For other archive formats, see the :mod:`gzip`, :mod:`zipfile`, and
+:mod:`tarfile` modules.
+
+Here is a summary of the features offered by the bz2 module:
 
 * :class:`BZ2File` class implements a complete file interface, including
   :meth:`readline`, :meth:`readlines`, :meth:`writelines`, :meth:`seek`, etc;
@@ -30,9 +33,7 @@
 * One-shot (de)compression supported by :func:`compress` and :func:`decompress`
   functions;
 
-* Thread safety uses individual locking mechanism;
-
-* Complete inline documentation;
+* Thread safety uses individual locking mechanism.
 
 
 (De)compression of files
diff --git a/Doc/library/csv.rst b/Doc/library/csv.rst
index 598dc50..5e1bd1e 100644
--- a/Doc/library/csv.rst
+++ b/Doc/library/csv.rst
@@ -124,6 +124,10 @@
    Return the dialect associated with *name*.  An :exc:`Error` is raised if *name*
    is not a registered dialect name.
 
+   .. versionchanged:: 2.5
+      This function now returns an immutable :class:`Dialect`.  Previously an
+      instance of the requested dialect was returned.  Users could modify the
+      underlying class, changing the behavior of active readers and writers.
 
 .. function:: list_dialects()
 
diff --git a/Doc/library/gzip.rst b/Doc/library/gzip.rst
index 5978031..d298f88 100644
--- a/Doc/library/gzip.rst
+++ b/Doc/library/gzip.rst
@@ -15,6 +15,9 @@
 programs, such  as those produced by :program:`compress` and :program:`pack`,
 are not supported by this module.
 
+For other archive formats, see the :mod:`bz2`, :mod:`zipfile`, and
+:mod:`tarfile` modules.
+
 The module defines the following items:
 
 
diff --git a/Doc/library/tarfile.rst b/Doc/library/tarfile.rst
index 4aabd81..7893ccd 100644
--- a/Doc/library/tarfile.rst
+++ b/Doc/library/tarfile.rst
@@ -11,10 +11,13 @@
 .. sectionauthor:: Lars Gustäbel <lars@gustaebel.de>
 
 
-The :mod:`tarfile` module makes it possible to read and create tar archives.
+The :mod:`tarfile` module makes it possible to read and write tar
+archives, including those using gzip or bz2 compression.
+(`.zip` files can be read and written using the :mod:`zipfile` module.)
+
 Some facts and figures:
 
-* reads and writes :mod:`gzip` and :mod:`bzip2` compressed archives.
+* reads and writes :mod:`gzip` and :mod:`bz2` compressed archives.
 
 * read/write support for the POSIX.1-1988 (ustar) format.
 
diff --git a/Doc/library/zipfile.rst b/Doc/library/zipfile.rst
index 92a4526..6c946f8 100644
--- a/Doc/library/zipfile.rst
+++ b/Doc/library/zipfile.rst
@@ -16,14 +16,18 @@
 defined in `PKZIP Application Note
 <http://www.pkware.com/business_and_developers/developer/appnote/>`_.
 
-This module does not currently handle ZIP files which have appended comments, or
-multi-disk ZIP files. It can handle ZIP files that use the ZIP64 extensions
-(that is ZIP files that are more than 4 GByte in size).  It supports decryption
-of encrypted files in ZIP archives, but it cannot currently create an encrypted
-file.
+This module does not currently handle multi-disk ZIP files, or ZIP files
+which have appended comments (although it correctly handles comments
+added to individual archive members---for which see the :ref:`zipinfo-objects`
+documentation). It can handle ZIP files that use the ZIP64 extensions
+(that is ZIP files that are more than 4 GByte in size).  It supports
+decryption of encrypted files in ZIP archives, but it currently cannot
+create an encrypted file.
 
-The available attributes of this module are:
+For other archive formats, see the :mod:`bz2`, :mod:`gzip`, and
+:mod:`tarfile` modules.
 
+The module defines the following items:
 
 .. exception:: BadZipfile
 
diff --git a/Doc/library/zlib.rst b/Doc/library/zlib.rst
index 3f051a7..449394c 100644
--- a/Doc/library/zlib.rst
+++ b/Doc/library/zlib.rst
@@ -19,6 +19,10 @@
 consult the zlib manual at http://www.zlib.net/manual.html for authoritative
 information.
 
+For reading and writing ``.gz`` files see the :mod:`gzip` module. For
+other archive formats, see the :mod:`bz2`, :mod:`zipfile`, and
+:mod:`tarfile` modules.
+
 The available exception and functions in this module are:
 
 
diff --git a/Lib/bsddb/test/test_lock.py b/Lib/bsddb/test/test_lock.py
index fcab283..bbd88bd 100644
--- a/Lib/bsddb/test/test_lock.py
+++ b/Lib/bsddb/test/test_lock.py
@@ -2,11 +2,12 @@
 TestCases for testing the locking sub-system.
 """
 
+import os
+from pprint import pprint
 import shutil
-import sys, os
+import sys
 import tempfile
 import time
-from pprint import pprint
 
 try:
     from threading import Thread, currentThread
@@ -31,10 +32,10 @@
 class LockingTestCase(unittest.TestCase):
 
     def setUp(self):
-        self.homeDir = tempfile.mkdtemp()
+        self.homeDir = tempfile.mkdtemp('.test_lock')
         self.env = db.DBEnv()
         self.env.open(self.homeDir, db.DB_THREAD | db.DB_INIT_MPOOL |
-                      db.DB_INIT_LOCK | db.DB_CREATE)
+                                    db.DB_INIT_LOCK | db.DB_CREATE)
 
 
     def tearDown(self):
@@ -57,8 +58,8 @@
         self.env.lock_put(lock)
         if verbose:
             print("Released lock: %s" % lock)
-
-
+        if db.version() >= (4,0):
+            self.env.lock_id_free(anID)
 
 
     def test02_threaded(self):
@@ -119,6 +120,8 @@
         self.env.lock_put(lock)
         if verbose:
             print("%s: Released %s lock: %s" % (name, lt, lock))
+        if db.version() >= (4,0):
+            self.env.lock_id_free(anID)
 
 
 #----------------------------------------------------------------------
diff --git a/Lib/bsddb/test/test_misc.py b/Lib/bsddb/test/test_misc.py
index b3248ce..b7a6710 100644
--- a/Lib/bsddb/test/test_misc.py
+++ b/Lib/bsddb/test/test_misc.py
@@ -85,6 +85,34 @@
             db1.close()
             os.unlink(self.filename)
 
+    def test_DB_set_flags_persists(self):
+        if db.version() < (4,2):
+            # The get_flags API required for this to work is only available
+            # in BerkeleyDB >= 4.2
+            return
+        try:
+            db1 = db.DB()
+            db1.set_flags(db.DB_DUPSORT)
+            db1.open(self.filename, db.DB_HASH, db.DB_CREATE)
+            db1[b'a'] = b'eh'
+            db1[b'a'] = b'A'
+            self.assertEqual([(b'a', b'A')], db1.items())
+            db1.put(b'a', b'Aa')
+            self.assertEqual([(b'a', b'A'), (b'a', b'Aa')], db1.items())
+            db1.close()
+            db1 = db.DB()
+            # no set_flags call, we're testing that it reads and obeys
+            # the flags on open.
+            db1.open(self.filename, db.DB_HASH)
+            self.assertEqual([(b'a', b'A'), (b'a', b'Aa')], db1.items())
+            # if it read the flags right this will replace all values
+            # for key b'a' instead of adding a new one.  (as a dict should)
+            db1[b'a'] = b'new A'
+            self.assertEqual([(b'a', b'new A')], db1.items())
+        finally:
+            db1.close()
+            os.unlink(self.filename)
+
 
 #----------------------------------------------------------------------
 
diff --git a/Modules/_bsddb.c b/Modules/_bsddb.c
index 8414618..bd1c271 100644
--- a/Modules/_bsddb.c
+++ b/Modules/_bsddb.c
@@ -1940,21 +1940,6 @@
         return NULL;
     }
 
-#if 0 && (DBVER >= 41)
-    if ((!txn) && (txnobj != Py_None) && self->myenvobj
-        && (self->myenvobj->flags & DB_INIT_TXN))
-    {
-	/* If no 'txn' parameter was supplied (no DbTxn object and None was not
-	 * explicitly passed) but we are in a transaction ready environment:
-	 *   add DB_AUTO_COMMIT to allow for older pybsddb apps using transactions
-	 *   to work on BerkeleyDB 4.1 without needing to modify their
-	 *   DBEnv or DB open calls. 
-	 * TODO make this behaviour of the library configurable.
-	 */
-	flags |= DB_AUTO_COMMIT;
-    }
-#endif
-
     MYDB_BEGIN_ALLOW_THREADS;
 #if (DBVER >= 41)
     err = self->db->open(self->db, txn, filename, dbname, type, flags, mode);
@@ -1968,6 +1953,10 @@
         return NULL;
     }
 
+#if (DBVER >= 42)
+    self->db->get_flags(self->db, &self->setflags);
+#endif
+
     self->flags = flags;
     RETURN_NONE();
 }
@@ -4390,6 +4379,24 @@
     return PyInt_FromLong((long)theID);
 }
 
+#if (DBVER >= 40)
+static PyObject*
+DBEnv_lock_id_free(DBEnvObject* self, PyObject* args)
+{
+    int err;
+    u_int32_t theID;
+
+    if (!PyArg_ParseTuple(args, "I:lock_id_free", &theID))
+        return NULL;
+
+    CHECK_ENV_NOT_CLOSED(self);
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->db_env->lock_id_free(self->db_env, theID);
+    MYDB_END_ALLOW_THREADS;
+    RETURN_IF_ERR();
+    RETURN_NONE();
+}
+#endif
 
 static PyObject*
 DBEnv_lock_put(DBEnvObject* self, PyObject* args)
@@ -5266,6 +5273,9 @@
     {"lock_detect",     (PyCFunction)DBEnv_lock_detect,      METH_VARARGS},
     {"lock_get",        (PyCFunction)DBEnv_lock_get,         METH_VARARGS},
     {"lock_id",         (PyCFunction)DBEnv_lock_id,          METH_VARARGS},
+#if (DBVER >= 40)
+    {"lock_id_free",    (PyCFunction)DBEnv_lock_id_free,     METH_VARARGS},
+#endif
     {"lock_put",        (PyCFunction)DBEnv_lock_put,         METH_VARARGS},
     {"lock_stat",       (PyCFunction)DBEnv_lock_stat,        METH_VARARGS},
     {"log_archive",     (PyCFunction)DBEnv_log_archive,      METH_VARARGS},