#7905: Actually respect the keyencoding parameter to shelve.Shelf.

This commit is contained in:
Georg Brandl 2010-12-04 11:12:43 +00:00
parent c9fb3c6417
commit 732324a3f8
4 changed files with 28 additions and 5 deletions

View 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)

View 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():

View 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 = {}

View File

@ -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