mirror of https://github.com/python/cpython
gh-83383: Always mark the dbm.dumb database as unmodified after open() and sync() (GH-114560)
The directory file for a newly created database is now created immediately after opening instead of deferring this until synchronizing or closing.
This commit is contained in:
parent
ff7588b729
commit
fc06096911
|
@ -98,7 +98,8 @@ class _Database(collections.abc.MutableMapping):
|
|||
except OSError:
|
||||
if flag not in ('c', 'n'):
|
||||
raise
|
||||
self._modified = True
|
||||
with self._io.open(self._dirfile, 'w', encoding="Latin-1") as f:
|
||||
self._chmod(self._dirfile)
|
||||
else:
|
||||
with f:
|
||||
for line in f:
|
||||
|
@ -134,6 +135,7 @@ class _Database(collections.abc.MutableMapping):
|
|||
# position; UTF-8, though, does care sometimes.
|
||||
entry = "%r, %r\n" % (key.decode('Latin-1'), pos_and_siz_pair)
|
||||
f.write(entry)
|
||||
self._modified = False
|
||||
|
||||
sync = _commit
|
||||
|
||||
|
|
|
@ -246,9 +246,27 @@ class DumbDBMTestCase(unittest.TestCase):
|
|||
_delete_files()
|
||||
with self.assertRaises(FileNotFoundError):
|
||||
dumbdbm.open(_fname, value)
|
||||
self.assertFalse(os.path.exists(_fname + '.dat'))
|
||||
self.assertFalse(os.path.exists(_fname + '.dir'))
|
||||
self.assertFalse(os.path.exists(_fname + '.bak'))
|
||||
|
||||
for value in ('c', 'n'):
|
||||
_delete_files()
|
||||
with dumbdbm.open(_fname, value) as f:
|
||||
self.assertTrue(os.path.exists(_fname + '.dat'))
|
||||
self.assertTrue(os.path.exists(_fname + '.dir'))
|
||||
self.assertFalse(os.path.exists(_fname + '.bak'))
|
||||
self.assertFalse(os.path.exists(_fname + '.bak'))
|
||||
|
||||
for value in ('c', 'n'):
|
||||
_delete_files()
|
||||
with dumbdbm.open(_fname, value) as f:
|
||||
f['key'] = 'value'
|
||||
self.assertTrue(os.path.exists(_fname + '.dat'))
|
||||
self.assertTrue(os.path.exists(_fname + '.dir'))
|
||||
self.assertFalse(os.path.exists(_fname + '.bak'))
|
||||
self.assertTrue(os.path.exists(_fname + '.bak'))
|
||||
|
||||
def test_missing_index(self):
|
||||
with dumbdbm.open(_fname, 'n') as f:
|
||||
pass
|
||||
|
@ -259,6 +277,60 @@ class DumbDBMTestCase(unittest.TestCase):
|
|||
self.assertFalse(os.path.exists(_fname + '.dir'))
|
||||
self.assertFalse(os.path.exists(_fname + '.bak'))
|
||||
|
||||
for value in ('c', 'n'):
|
||||
with dumbdbm.open(_fname, value) as f:
|
||||
self.assertTrue(os.path.exists(_fname + '.dir'))
|
||||
self.assertFalse(os.path.exists(_fname + '.bak'))
|
||||
self.assertFalse(os.path.exists(_fname + '.bak'))
|
||||
os.unlink(_fname + '.dir')
|
||||
|
||||
for value in ('c', 'n'):
|
||||
with dumbdbm.open(_fname, value) as f:
|
||||
f['key'] = 'value'
|
||||
self.assertTrue(os.path.exists(_fname + '.dir'))
|
||||
self.assertFalse(os.path.exists(_fname + '.bak'))
|
||||
self.assertTrue(os.path.exists(_fname + '.bak'))
|
||||
os.unlink(_fname + '.dir')
|
||||
os.unlink(_fname + '.bak')
|
||||
|
||||
def test_sync_empty_unmodified(self):
|
||||
with dumbdbm.open(_fname, 'n') as f:
|
||||
pass
|
||||
os.unlink(_fname + '.dir')
|
||||
for value in ('c', 'n'):
|
||||
with dumbdbm.open(_fname, value) as f:
|
||||
self.assertTrue(os.path.exists(_fname + '.dir'))
|
||||
self.assertFalse(os.path.exists(_fname + '.bak'))
|
||||
f.sync()
|
||||
self.assertTrue(os.path.exists(_fname + '.dir'))
|
||||
self.assertFalse(os.path.exists(_fname + '.bak'))
|
||||
os.unlink(_fname + '.dir')
|
||||
f.sync()
|
||||
self.assertFalse(os.path.exists(_fname + '.dir'))
|
||||
self.assertFalse(os.path.exists(_fname + '.bak'))
|
||||
self.assertFalse(os.path.exists(_fname + '.dir'))
|
||||
self.assertFalse(os.path.exists(_fname + '.bak'))
|
||||
|
||||
def test_sync_nonempty_unmodified(self):
|
||||
with dumbdbm.open(_fname, 'n') as f:
|
||||
pass
|
||||
os.unlink(_fname + '.dir')
|
||||
for value in ('c', 'n'):
|
||||
with dumbdbm.open(_fname, value) as f:
|
||||
f['key'] = 'value'
|
||||
self.assertTrue(os.path.exists(_fname + '.dir'))
|
||||
self.assertFalse(os.path.exists(_fname + '.bak'))
|
||||
f.sync()
|
||||
self.assertTrue(os.path.exists(_fname + '.dir'))
|
||||
self.assertTrue(os.path.exists(_fname + '.bak'))
|
||||
os.unlink(_fname + '.dir')
|
||||
os.unlink(_fname + '.bak')
|
||||
f.sync()
|
||||
self.assertFalse(os.path.exists(_fname + '.dir'))
|
||||
self.assertFalse(os.path.exists(_fname + '.bak'))
|
||||
self.assertFalse(os.path.exists(_fname + '.dir'))
|
||||
self.assertFalse(os.path.exists(_fname + '.bak'))
|
||||
|
||||
def test_invalid_flag(self):
|
||||
for flag in ('x', 'rf', None):
|
||||
with self.assertRaisesRegex(ValueError,
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
Synchronization of the :mod:`dbm.dumb` database is now no-op if there was no
|
||||
modification since opening or last synchronization.
|
||||
The directory file for a newly created empty :mod:`dbm.dumb` database is now
|
||||
created immediately after opening instead of deferring this until
|
||||
synchronizing or closing.
|
Loading…
Reference in New Issue