Atomic file save -- code review and comments requested
Steven D'Aprano
steve at pearwood.info
Wed Sep 2 14:02:43 EDT 2015
Howdy,
I have a utility function for performing atomic file saves, and I'd like to
ask for a code review and comments.
I have published this on ActiveState:
https://code.activestate.com/recipes/579097-safely-and-atomically-write-to-a-file/
under an MIT licence. You should read the version there, I discuss the
use-case for the function and include an extensive doc string. Feel free to
comment either here or on the ActiveState site.
Here is the function, minus the docstring (for brevity):
import contextlib
import os
import stat
import tempfile
@contextlib.contextmanager
def atomic_write(filename, text=True, keep=True,
owner=None, group=None, perms=None,
suffix='.bak', prefix='tmp'):
t = (uid, gid, mod) = (owner, group, perms)
if any(x is None for x in t):
info = os.stat(filename)
if uid is None:
uid = info.st_uid
if gid is None:
gid = info.st_gid
if mod is None:
mod = stat.S_IMODE(info.st_mode)
path = os.path.dirname(filename)
fd, tmp = tempfile.mkstemp(
suffix=suffix, prefix=prefix, dir=path, text=text)
try:
with os.fdopen(fd, 'w' if text else 'wb') as f:
yield f
os.rename(tmp, filename)
tmp = None
os.chown(filename, uid, gid)
os.chmod(filename, mod)
finally:
if (tmp is not None) and (not keep):
# Silently delete the temporary file. Ignore any errors.
try:
os.unlink(tmp)
except:
pass
Usage is:
with atomic_write("mydata.txt") as f:
f.write("some data")
# if an error occurs in here, mydata.txt is preserved
# if no error occurs and the with-block exits cleanly,
# mydata.txt is atomically overwritten with the new contents.
The function is written for Python 2.6, but should work on 2.7 as well.
I'm looking for a review of the code, and any general comments. In
particular, have I missed any ways that the function may fail and lose
data?
One question comes to mind -- should I perform a flush and/or sync of the
file before the rename?
Thanks in advance for all constructive comments.
--
Steven
More information about the Python-list
mailing list