[Python-checkins] cpython (3.5): Issue #28847: dbm.dumb now supports reading read-only files and no longer

serhiy.storchaka python-checkins at python.org
Wed Dec 7 04:11:43 EST 2016


https://hg.python.org/cpython/rev/0a74bc7ba462
changeset: 105501:0a74bc7ba462
branch: 3.5
parent: 105478:104fdc42bcd1
user: Serhiy Storchaka <storchaka at gmail.com>
date: Wed Dec 07 10:56:39 2016 +0200
summary:
 Issue #28847: dbm.dumb now supports reading read-only files and no longer
writes the index file when it is not changed.
files:
 Lib/dbm/dumb.py | 8 ++++++--
 Lib/test/support/__init__.py | 6 +++---
 Lib/test/test_dbm_dumb.py | 16 ++++++++++++++++
 Misc/NEWS | 3 +++
 4 files changed, 28 insertions(+), 5 deletions(-)
diff --git a/Lib/dbm/dumb.py b/Lib/dbm/dumb.py
--- a/Lib/dbm/dumb.py
+++ b/Lib/dbm/dumb.py
@@ -47,6 +47,7 @@
 
 def __init__(self, filebasename, mode, flag='c'):
 self._mode = mode
+ self._readonly = (flag == 'r')
 
 # The directory file is a text file. Each line looks like
 # "%r, (%d, %d)\n" % (key, pos, siz)
@@ -91,8 +92,9 @@
 try:
 f = _io.open(self._dirfile, 'r', encoding="Latin-1")
 except OSError:
- pass
+ self._modified = not self._readonly
 else:
+ self._modified = False
 with f:
 for line in f:
 line = line.rstrip()
@@ -107,7 +109,7 @@
 # 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:
+ if self._index is None or not self._modified:
 return # nothing to do
 
 try:
@@ -187,6 +189,7 @@
 elif not isinstance(val, (bytes, bytearray)):
 raise TypeError("values must be bytes or strings")
 self._verify_open()
+ self._modified = True
 if key not in self._index:
 self._addkey(key, self._addval(val))
 else:
@@ -215,6 +218,7 @@
 if isinstance(key, str):
 key = key.encode('utf-8')
 self._verify_open()
+ self._modified = True
 # The blocks used by the associated value are lost.
 del self._index[key]
 # XXX It's unclear why we do a _commit() here (the code always
diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py
--- a/Lib/test/support/__init__.py
+++ b/Lib/test/support/__init__.py
@@ -359,9 +359,9 @@
 mode = 0
 if stat.S_ISDIR(mode):
 _waitfor(_rmtree_inner, fullname, waitall=True)
- _force_run(path, os.rmdir, fullname)
+ _force_run(fullname, os.rmdir, fullname)
 else:
- _force_run(path, os.unlink, fullname)
+ _force_run(fullname, os.unlink, fullname)
 _waitfor(_rmtree_inner, path, waitall=True)
 _waitfor(lambda p: _force_run(p, os.rmdir, p), path)
 else:
@@ -933,7 +933,7 @@
 yield path
 finally:
 if dir_created:
- shutil.rmtree(path)
+ rmtree(path)
 
 @contextlib.contextmanager
 def change_cwd(path, quiet=False):
diff --git a/Lib/test/test_dbm_dumb.py b/Lib/test/test_dbm_dumb.py
--- 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 @@
 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:
+ fname = os.path.join(dir, 'db')
+ with dumbdbm.open(fname, 'n') as f:
+ self.assertEqual(list(f.keys()), [])
+ for key in self._dict:
+ f[key] = self._dict[key]
+ os.chmod(fname + ".dir", stat.S_IRUSR)
+ os.chmod(fname + ".dat", stat.S_IRUSR)
+ os.chmod(dir, stat.S_IRUSR|stat.S_IXUSR)
+ with dumbdbm.open(fname, 'r') as f:
+ self.assertEqual(sorted(f.keys()), sorted(self._dict))
+ f.close() # don't write
+
 def tearDown(self):
 _delete_files()
 
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -121,6 +121,9 @@
 Library
 -------
 
+- Issue #28847: dbm.dumb now supports reading read-only files and no longer
+ writes the index file when it is not changed.
+
 - Issue #25659: In ctypes, prevent a crash calling the from_buffer() and
 from_buffer_copy() methods on abstract classes like Array.
 
-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /