'Get a write transaction on a file cache item.
Returns a WriteTransaction context manager that opens a temporary file
for writing.  Once the context manager finishes, if nothing went wrong,
moves the file into place on top of the old file atomically.'

def write_transaction(self, key):

    class WriteContextManager(object, ):
        def __enter__(cm):
            cm.orig_filename = self.cache_path(key)
            cm.orig_file = None
            if os.path.exists(cm.orig_filename):
                cm.orig_file = open(cm.orig_filename, 'r')
            cm.tmp_filename = (self.cache_path(key) + '.tmp')
            cm.tmp_file = open(cm.tmp_filename, 'w')
            return (cm.orig_file, cm.tmp_file)
        def __exit__(cm, type, value, traceback):
            if cm.orig_file:
                cm.orig_file.close()
            cm.tmp_file.close()
            if value:
                shutil.rmtree(cm.tmp_filename, True)
            else:
                os.rename(cm.tmp_filename, cm.orig_filename)
    return WriteTransaction(self._get_lock(key), WriteContextManager)
