#7905: Actually respect the keyencoding parameter to shelve.Shelf.
authorGeorg Brandl <georg@python.org>
Sat, 4 Dec 2010 11:12:43 +0000 (11:12 +0000)
committerGeorg Brandl <georg@python.org>
Sat, 4 Dec 2010 11:12:43 +0000 (11:12 +0000)
Doc/library/shelve.rst
Lib/shelve.py
Lib/test/test_shelve.py
Misc/NEWS

index 512788c9c997813ce1f03d82726c21b5db91f20a..de2283351f25a5d001e66c1958803ce7c94631c5 100644 (file)
@@ -101,7 +101,7 @@ Restrictions
   implementation used.
 
 
-.. class:: Shelf(dict, protocol=None, writeback=False)
+.. class:: Shelf(dict, protocol=None, writeback=False, keyencoding='utf-8')
 
    A subclass of :class:`collections.MutableMapping` which stores pickled values
    in the *dict* object.
@@ -115,8 +115,15 @@ Restrictions
    This allows natural operations on mutable entries, but can consume much more
    memory and make sync and close take a long time.
 
+   The *keyencoding* parameter is the encoding used to encode keys before they
+   are used with the underlying dict.
 
-.. class:: BsdDbShelf(dict, protocol=None, writeback=False)
+   .. versionadded:: 3.2
+      The *keyencoding* parameter; previously, keys were always encoded in
+      UTF-8.
+
+
+.. class:: BsdDbShelf(dict, protocol=None, writeback=False, keyencoding='utf-8')
 
    A subclass of :class:`Shelf` which exposes :meth:`first`, :meth:`!next`,
    :meth:`previous`, :meth:`last` and :meth:`set_location` which are available
@@ -125,8 +132,8 @@ Restrictions
    modules.  The *dict* object passed to the constructor must support those
    methods.  This is generally accomplished by calling one of
    :func:`bsddb.hashopen`, :func:`bsddb.btopen` or :func:`bsddb.rnopen`.  The
-   optional *protocol* and *writeback* parameters have the same interpretation
-   as for the :class:`Shelf` class.
+   optional *protocol*, *writeback*, and *keyencoding* parameters have the same
+   interpretation as for the :class:`Shelf` class.
 
 
 .. class:: DbfilenameShelf(filename, flag='c', protocol=None, writeback=False)
index 52e471ac863a31708d9ead4cd5ea8cf233326531..cc1815e3eb881ad66d7cfecb000bbeac72d8e1ea 100644 (file)
@@ -73,6 +73,7 @@ class _ClosedDict(collections.MutableMapping):
     def __repr__(self):
         return '<Closed Dictionary>'
 
+
 class Shelf(collections.MutableMapping):
     """Base class for shelf implementations.
 
@@ -88,7 +89,7 @@ class Shelf(collections.MutableMapping):
         self._protocol = protocol
         self.writeback = writeback
         self.cache = {}
-        self.keyencoding = "utf-8"
+        self.keyencoding = keyencoding
 
     def __iter__(self):
         for k in self.dict.keys():
index 066208a1c073e6e7cd72102c9cf099b3b7d1f99e..3e73f52b87b20cf50fca3f09ffb7fb245818c5ba 100644 (file)
@@ -122,6 +122,19 @@ class TestCase(unittest.TestCase):
         self.assertEqual(len(d1), 1)
         self.assertEqual(len(d2), 1)
 
+    def test_keyencoding(self):
+        d = {}
+        key = 'Pöp'
+        # the default keyencoding is utf-8
+        shelve.Shelf(d)[key] = [1]
+        self.assertIn(key.encode('utf-8'), d)
+        # but a different one can be given
+        shelve.Shelf(d, keyencoding='latin1')[key] = [1]
+        self.assertIn(key.encode('latin1'), d)
+        # with all consequences
+        s = shelve.Shelf(d, keyencoding='ascii')
+        self.assertRaises(UnicodeEncodeError, s.__setitem__, key, [1])
+
     def test_writeback_also_writes_immediately(self):
         # Issue 5754
         d = {}
index 3d959c25b5a8631e54238ab83f5cb0ee6b1cbbd8..cbdeb6dfa4f4608849c5042eff0c5d3a25d54b17 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -45,6 +45,8 @@ Core and Builtins
 Library
 -------
 
+- Issue #7905: Actually respect the keyencoding parameter to shelve.Shelf.
+
 - Issue #1569291: Speed up array.repeat().
 
 - Provide an interface to set the optimization level of compilation in