@contextmanager
def atomic_output_file(dest_path, make_parents=False, backup_suffix=None, suffix=".partial.%s"):
  '''
  A context manager for convenience in writing a file 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, if present.
  '''
  tmp_path = ("%s" + suffix) % (dest_path, new_uid())
  if make_parents:
    make_parent_dirs(tmp_path)
  yield tmp_path
  if not os.path.isfile(tmp_path):
    raise BadState("failure in writing file: %s (temp location %s)" % (dest_path, tmp_path))
  move_to_backup(dest_path, backup_suffix=backup_suffix)
  shutil.move(tmp_path, dest_path)
dataset/ETHPy150Open bloomreach/zinc/zinc.py/atomic_output_file/original