Kaydet (Commit) 9bd44d6d authored tarafından Serhiy Storchaka's avatar Serhiy Storchaka

Issue #28847: dubmdbm no longer writes the index file in when it is not

changed and supports reading read-only files.
üst 6df26b5f
......@@ -45,8 +45,9 @@ class _Database(UserDict.DictMixin):
_os = _os # for _commit()
_open = _open # for _commit()
def __init__(self, filebasename, mode):
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)
......@@ -81,8 +82,9 @@ class _Database(UserDict.DictMixin):
try:
f = _open(self._dirfile)
except IOError:
pass
self._modified = not self._readonly
else:
self._modified = False
with f:
for line in f:
line = line.rstrip()
......@@ -96,7 +98,7 @@ class _Database(UserDict.DictMixin):
# 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:
......@@ -159,6 +161,7 @@ class _Database(UserDict.DictMixin):
def __setitem__(self, key, val):
if not type(key) == type('') == type(val):
raise TypeError, "keys and values must be strings"
self._modified = True
if key not in self._index:
self._addkey(key, self._addval(val))
else:
......@@ -184,6 +187,7 @@ class _Database(UserDict.DictMixin):
# (so that _commit() never gets called).
def __delitem__(self, key):
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
......@@ -246,4 +250,4 @@ def open(file, flag=None, mode=0666):
# Turn off any bits that are set in the umask
mode = mode & (~um)
return _Database(file, mode)
return _Database(file, mode, flag)
......@@ -3,6 +3,7 @@
"""
import os
import stat
import unittest
import dumbdbm
from test import test_support
......@@ -168,6 +169,26 @@ class DumbDBMTestCase(unittest.TestCase):
dumbdbm.open(_fname).close()
self.assertEqual(stdout.getvalue(), '')
@unittest.skipUnless(hasattr(os, 'chmod'), 'test needs os.chmod()')
def test_readonly_files(self):
dir = _fname
os.mkdir(dir)
try:
fname = os.path.join(dir, 'db')
f = dumbdbm.open(fname, 'n')
self.assertEqual(list(f.keys()), [])
for key in self._dict:
f[key] = self._dict[key]
f.close()
os.chmod(fname + ".dir", stat.S_IRUSR)
os.chmod(fname + ".dat", stat.S_IRUSR)
os.chmod(dir, stat.S_IRUSR|stat.S_IXUSR)
f = dumbdbm.open(fname, 'r')
self.assertEqual(sorted(f.keys()), sorted(self._dict))
f.close() # don't write
finally:
test_support.rmtree(dir)
def tearDown(self):
_delete_files()
......
......@@ -10,6 +10,9 @@ What's New in Python 2.7.13?
Core and Builtins
-----------------
- Issue #28847: dubmdbm no longer writes the index file in when it is not
changed and supports reading read-only files.
- Issue #11145: Fixed miscellaneous issues with C-style formatting of types
with custom __oct__ and __hex__.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment