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 -- https://mail.python.org/mailman/listinfo/python-list