cpython: 0a74bc7ba462 (original) (raw)
Mercurial > cpython
changeset 105501:0a74bc7ba462 3.5
Issue #28847: dbm.dumb now supports reading read-only files and no longer writes the index file when it is not changed. [#28847]
Serhiy Storchaka storchaka@gmail.com | |
---|---|
date | Wed, 07 Dec 2016 10:56:39 +0200 |
parents | 104fdc42bcd1 |
children | 0c532bd28539 1f31bf3f76f5 |
files | Lib/dbm/dumb.py Lib/test/support/__init__.py Lib/test/test_dbm_dumb.py Misc/NEWS |
diffstat | 4 files changed, 28 insertions(+), 5 deletions(-)[+] [-] Lib/dbm/dumb.py 8 Lib/test/support/__init__.py 6 Lib/test/test_dbm_dumb.py 16 Misc/NEWS 3 |
line wrap: on
line diff
--- a/Lib/dbm/dumb.py +++ b/Lib/dbm/dumb.py @@ -47,6 +47,7 @@ class _Database(collections.MutableMappi def init(self, filebasename, mode, flag='c'): self._mode = mode
self._readonly = (flag == 'r')[](#l1.7)
# The directory file is a text file. Each line looks like # "%r, (%d, %d)\n" % (key, pos, siz) @@ -91,8 +92,9 @@ class _Database(collections.MutableMappi try: f = _io.open(self._dirfile, 'r', encoding="Latin-1") except OSError:
pass[](#l1.15)
self._modified = not self._readonly[](#l1.16) else:[](#l1.17)
self._modified = False[](#l1.18) with f:[](#l1.19) for line in f:[](#l1.20) line = line.rstrip()[](#l1.21)
@@ -107,7 +109,7 @@ class _Database(collections.MutableMappi # CAUTION: It's vital that _commit() succeed, and _commit() can # be called from del(). Therefore we must never reference a # global in this routine.
if self._index is None:[](#l1.26)
if self._index is None or not self._modified:[](#l1.27) return # nothing to do[](#l1.28)
try: @@ -187,6 +189,7 @@ class _Database(collections.MutableMappi elif not isinstance(val, (bytes, bytearray)): raise TypeError("values must be bytes or strings") self._verify_open()
self._modified = True[](#l1.35) if key not in self._index:[](#l1.36) self._addkey(key, self._addval(val))[](#l1.37) else:[](#l1.38)
@@ -215,6 +218,7 @@ class _Database(collections.MutableMappi if isinstance(key, str): key = key.encode('utf-8') self._verify_open()
self._modified = True[](#l1.43) # The blocks used by the associated value are lost.[](#l1.44) del self._index[key][](#l1.45) # XXX It's unclear why we do a _commit() here (the code always[](#l1.46)
--- a/Lib/test/support/init.py +++ b/Lib/test/support/init.py @@ -359,9 +359,9 @@ if sys.platform.startswith("win"): mode = 0 if stat.S_ISDIR(mode): _waitfor(_rmtree_inner, fullname, waitall=True)
_force_run(path, os.rmdir, fullname)[](#l2.7)
_force_run(fullname, os.rmdir, fullname)[](#l2.8) else:[](#l2.9)
_force_run(path, os.unlink, fullname)[](#l2.10)
_force_run(fullname, os.unlink, fullname)[](#l2.11) _waitfor(_rmtree_inner, path, waitall=True)[](#l2.12) _waitfor(lambda p: _force_run(p, os.rmdir, p), path)[](#l2.13)
else: @@ -933,7 +933,7 @@ def temp_dir(path=None, quiet=False): yield path finally: if dir_created:
shutil.rmtree(path)[](#l2.19)
rmtree(path)[](#l2.20)
@contextlib.contextmanager def change_cwd(path, quiet=False):
--- a/Lib/test/test_dbm_dumb.py +++ b/Lib/test/test_dbm_dumb.py @@ -5,6 +5,7 @@ import io import operator import os +import stat import unittest import dbm.dumb as dumbdbm from test import support @@ -234,6 +235,21 @@ class DumbDBMTestCase(unittest.TestCase) pass self.assertEqual(stdout.getvalue(), '')
- @unittest.skipUnless(hasattr(os, 'chmod'), 'test needs os.chmod()')
- def test_readonly_files(self):
with support.temp_dir() as dir:[](#l3.17)
fname = os.path.join(dir, 'db')[](#l3.18)
with dumbdbm.open(fname, 'n') as f:[](#l3.19)
self.assertEqual(list(f.keys()), [])[](#l3.20)
for key in self._dict:[](#l3.21)
f[key] = self._dict[key][](#l3.22)
os.chmod(fname + ".dir", stat.S_IRUSR)[](#l3.23)
os.chmod(fname + ".dat", stat.S_IRUSR)[](#l3.24)
os.chmod(dir, stat.S_IRUSR|stat.S_IXUSR)[](#l3.25)
with dumbdbm.open(fname, 'r') as f:[](#l3.26)
self.assertEqual(sorted(f.keys()), sorted(self._dict))[](#l3.27)
f.close() # don't write[](#l3.28)
+ def tearDown(self): _delete_files()
--- a/Misc/NEWS +++ b/Misc/NEWS @@ -121,6 +121,9 @@ Core and Builtins Library ------- +- Issue #28847: dbm.dumb now supports reading read-only files and no longer