Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion Lib/dbm/dumb.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,8 @@ def _verify_open(self):
def __getitem__(self, key):
if isinstance(key, str):
key = key.encode('utf-8')
elif isinstance(key, bytearray):
key = bytes(key)
self._verify_open()
pos, siz = self._index[key] # may raise KeyError
with _io.open(self._datfile, 'rb') as f:
Expand Down Expand Up @@ -189,7 +191,9 @@ def __setitem__(self, key, val):
raise error('The database is opened for reading only')
if isinstance(key, str):
key = key.encode('utf-8')
elif not isinstance(key, (bytes, bytearray)):
elif isinstance(key, bytearray):
key = bytes(key)
elif not isinstance(key, bytes):
raise TypeError("keys must be bytes or strings")
if isinstance(val, str):
val = val.encode('utf-8')
Expand Down Expand Up @@ -226,6 +230,8 @@ def __delitem__(self, key):
raise error('The database is opened for reading only')
if isinstance(key, str):
key = key.encode('utf-8')
elif isinstance(key, bytearray):
key = bytes(key)
self._verify_open()
self._modified = True
# The blocks used by the associated value are lost.
Expand All @@ -249,6 +255,8 @@ def items(self):
def __contains__(self, key):
if isinstance(key, str):
key = key.encode('utf-8')
elif isinstance(key, bytearray):
key = bytes(key)
try:
return key in self._index
except TypeError:
Expand Down
9 changes: 9 additions & 0 deletions Lib/test/test_dbm_dumb.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,15 @@ def test_dumbdbm_creation(self):
f[key] = self._dict[key]
self.read_helper(f)

def test_dumbdbm_bytearray_keys(self):
# gh-158217: bytearray keys must not raise TypeError:
with contextlib.closing(dumbdbm.open(_fname, 'c')) as f:
f[bytearray(b'key')] = b'value'
self.assertEqual(f[bytearray(b'key')], b'value')
self.assertIn(bytearray(b'key'), f)
del f[bytearray(b'key')]
self.assertNotIn(bytearray(b'key'), f)

@unittest.skipUnless(hasattr(os, 'umask'), 'test needs os.umask()')
@os_helper.skip_unless_working_chmod
def test_dumbdbm_creation_mode(self):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fix :mod:`dbm.dumb` to accept ``bytearray`` keys, consistent with the
other :mod:`dbm` backends. Patch by Tony Leung.
Loading