def atomic_output_file(dest_path, make_parents=False, backup_suffix=None, suffix=".partial.%s"):
  """
  A context manager for convenience in writing a file or directory in an atomic way. Set up
  a temporary name, then rename it after the operation is done, optionally making a backup of
  the previous file or directory, if present.
  """
  if dest_path == os.devnull:
    # Handle the (probably rare) case of writing to /dev/null.
    yield dest_path
  else:
    tmp_path = ("%s" + suffix) % (dest_path, new_uid())
    if make_parents:
      make_parent_dirs(tmp_path)

    yield tmp_path

    # Note this is not in a finally block, so that result won't be renamed to final location
    # in case of abnormal exit.
    if not os.path.exists(tmp_path):
      raise IOError("failure in writing file '%s': target file '%s' missing" % (dest_path, tmp_path))
    if backup_suffix:
      move_to_backup(dest_path, backup_suffix=backup_suffix)
    # If the target already exists, and is a directory, it has to be removed.
    if os.path.isdir(dest_path):
      shutil.rmtree(dest_path)
    shutil.move(tmp_path, dest_path)
A context manager for convenience in writing a file or directory in an atomic way. Set up
  a temporary name, then rename it after the operation is done, optionally making a backup of
  the previous file or directory, if present.