Charles-François Natali added the comment: > (Note that the Beaker version would need to be enhanced with the extra API > parameters from Victor's version, as well as updated to use the exclusive > open and close-on-exec flags)
I think the API would be nicer if it was just a wrapper around the underlying temporary file object, delegating all methods except close() (sort of like the _TemporaryFileWrapper in tempfile). Something like (untested, not even foolproof-read) : class AtomicFile: def __init__(self, path): self.dest_path = path dirname, basename = os.path.split(self.dest_path) fd, temp_path = tempfile.mkstemp(prefix='.' + basename, dir=dirname) try: self.f = os.fdopen(fd, 'w') except: os.unlink(temp_path) raise self.temp_path = temp_path def close(self): self.f.close() os.rename(self.temp_path, self.dest_path) # copied from tempfile def __getattr__(self, name): # Attribute lookups are delegated to the underlying file # and cached for non-numeric results # (i.e. methods are cached, closed and friends are not) file = self.__dict__['file'] a = getattr(file, name) if not issubclass(type(a), type(0)): setattr(self, name, a) return a def __enter__self(): self.file.__enter__() return f def __exit__(self, exc, value, tb): if exc is None: self.close() else: self.file.close() os.remove(self.temp_path) This way, one just has to do: f = AtomicFile(path) and then use it as a normal file; it will automatically be committed (or rollback) when the file is closed, either because you're leaving the context manager, or because an explicit() close is called. It also makes it easier to use with legacy code/libraries accepting an open file (since no modification is needed), is less error-prone (since you don't have to remember to call special methods like destroy_temp/replace_dest), and leads to a more compact API (exactly the same as regular files). Otherwise, I think the calls to fsync() should be optional (maybe an option passed to the constructor): most of the time, you want atomicity but not durability (i.e. you don't really care if data is committed to disk), and you don't want to pay for the performance hit incurred by fsync(). Also, fsync() should also be done on the containing directory (which is not the case in Victor's version). ---------- _______________________________________ Python tracker <rep...@bugs.python.org> <http://bugs.python.org/issue8604> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com