Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 43153e4

Browse files
Issue #28847: dbm.dumb now supports reading read-only files and no longer
writes the index file when it is not changed.
2 parents c29ba8b + 520348e commit 43153e4

4 files changed

Lines changed: 26 additions & 4 deletions

File tree

Lib/dbm/dumb.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,9 @@ def _update(self):
9797
try:
9898
f = _io.open(self._dirfile, 'r', encoding="Latin-1")
9999
except OSError:
100-
pass
100+
self._modified = not self._readonly
101101
else:
102+
self._modified = False
102103
with f:
103104
for line in f:
104105
line = line.rstrip()
@@ -113,7 +114,7 @@ def _commit(self):
113114
# CAUTION: It's vital that _commit() succeed, and _commit() can
114115
# be called from __del__(). Therefore we must never reference a
115116
# global in this routine.
116-
if self._index is None:
117+
if self._index is None or not self._modified:
117118
return # nothing to do
118119

119120
try:
@@ -197,6 +198,7 @@ def __setitem__(self, key, val):
197198
elif not isinstance(val, (bytes, bytearray)):
198199
raise TypeError("values must be bytes or strings")
199200
self._verify_open()
201+
self._modified = True
200202
if key not in self._index:
201203
self._addkey(key, self._addval(val))
202204
else:
@@ -229,6 +231,7 @@ def __delitem__(self, key):
229231
if isinstance(key, str):
230232
key = key.encode('utf-8')
231233
self._verify_open()
234+
self._modified = True
232235
# The blocks used by the associated value are lost.
233236
del self._index[key]
234237
# XXX It's unclear why we do a _commit() here (the code always

Lib/test/support/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -360,9 +360,9 @@ def _rmtree_inner(path):
360360
mode = 0
361361
if stat.S_ISDIR(mode):
362362
_waitfor(_rmtree_inner, fullname, waitall=True)
363-
_force_run(path, os.rmdir, fullname)
363+
_force_run(fullname, os.rmdir, fullname)
364364
else:
365-
_force_run(path, os.unlink, fullname)
365+
_force_run(fullname, os.unlink, fullname)
366366
_waitfor(_rmtree_inner, path, waitall=True)
367367
_waitfor(lambda p: _force_run(p, os.rmdir, p), path)
368368
else:

Lib/test/test_dbm_dumb.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import io
66
import operator
77
import os
8+
import stat
89
import unittest
910
import warnings
1011
import dbm.dumb as dumbdbm
@@ -259,6 +260,21 @@ def test_invalid_flag(self):
259260
f = dumbdbm.open(_fname, flag)
260261
f.close()
261262

263+
@unittest.skipUnless(hasattr(os, 'chmod'), 'test needs os.chmod()')
264+
def test_readonly_files(self):
265+
with support.temp_dir() as dir:
266+
fname = os.path.join(dir, 'db')
267+
with dumbdbm.open(fname, 'n') as f:
268+
self.assertEqual(list(f.keys()), [])
269+
for key in self._dict:
270+
f[key] = self._dict[key]
271+
os.chmod(fname + ".dir", stat.S_IRUSR)
272+
os.chmod(fname + ".dat", stat.S_IRUSR)
273+
os.chmod(dir, stat.S_IRUSR|stat.S_IXUSR)
274+
with dumbdbm.open(fname, 'r') as f:
275+
self.assertEqual(sorted(f.keys()), sorted(self._dict))
276+
f.close() # don't write
277+
262278
def tearDown(self):
263279
_delete_files()
264280

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,9 @@ Core and Builtins
165165
Library
166166
-------
167167

168+
- Issue #28847: dbm.dumb now supports reading read-only files and no longer
169+
writes the index file when it is not changed.
170+
168171
- Issue #27030: Unknown escapes consisting of ``'\'`` and an ASCII letter in
169172
re.sub() replacement templates regular expressions now are errors.
170173

0 commit comments

Comments
 (0)