mirror of https://github.com/python/cpython
Issue #28847: dbm.dumb now supports reading read-only files and no longer
writes the index file when it is not changed.
This commit is contained in:
parent
e503126074
commit
028ace1ccb
|
@ -47,6 +47,7 @@ class _Database(collections.MutableMapping):
|
|||
|
||||
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 @@ class _Database(collections.MutableMapping):
|
|||
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 @@ class _Database(collections.MutableMapping):
|
|||
# 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 @@ class _Database(collections.MutableMapping):
|
|||
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 @@ class _Database(collections.MutableMapping):
|
|||
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
|
||||
|
|
|
@ -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)
|
||||
_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 @@ def temp_dir(path=None, quiet=False):
|
|||
yield path
|
||||
finally:
|
||||
if dir_created:
|
||||
shutil.rmtree(path)
|
||||
rmtree(path)
|
||||
|
||||
@contextlib.contextmanager
|
||||
def change_cwd(path, quiet=False):
|
||||
|
|
|
@ -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:
|
||||
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()
|
||||
|
||||
|
|
|
@ -121,6 +121,9 @@ Core and Builtins
|
|||
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.
|
||||
|
||||
|
|
Loading…
Reference in New Issue