Add a blurb (a Misc/NEWS entry) to the current CPython repo.

def add():
    """
Add a blurb (a Misc/NEWS entry) to the current CPython repo.
    """

    editor = find_editor()

    handle, tmp_path = tempfile.mkstemp(".rst")
    os.close(handle)
    atexit.register(lambda : os.unlink(tmp_path))

    def init_tmp_with_template():
        with open(tmp_path, "wt", encoding="utf-8") as file:
            # hack:
            # my editor likes to strip trailing whitespace from lines.
            # normally this is a good idea.  but in the case of the template
            # it's unhelpful.
            # so, manually ensure there's a space at the end of the bpo line.
            text = template

            bpo_line = ".. bpo:"
            without_space = "\n" + bpo_line + "\n"
            with_space = "\n" + bpo_line + " \n"
            if without_space not in text:
                sys.exit("Can't find BPO line to ensure there's a space on the end!")
            text = text.replace(without_space, with_space)
            file.write(text)

    init_tmp_with_template()

    # We need to be clever about EDITOR.
    # On the one hand, it might be a legitimate path to an
    #   executable containing spaces.
    # On the other hand, it might be a partial command-line
    #   with options.
    if shutil.which(editor):
        args = [editor]
    else:
        args = list(shlex.split(editor))
        if not shutil.which(args[0]):
            sys.exit(f("Invalid GIT_EDITOR / EDITOR value: {editor}"))
    args.append(tmp_path)

    while True:
        subprocess.run(args)

        failure = None
        blurb = Blurbs()
        try:
            blurb.load(tmp_path)
        except BlurbError as e:
            failure = str(e)

        if not failure:
            assert len(blurb) # if parse_blurb succeeds, we should always have a body
            if len(blurb) > 1:
                failure = "Too many entries!  Don't specify '..' on a line by itself."

        if failure:
            print()
            print(f("Error: {failure}"))
            print()
            try:
                prompt("Hit return to retry (or Ctrl-C to abort)")
            except KeyboardInterrupt:
                print()
                return
            print()
            continue
        break

    path = blurb.save_next()
    git_add_files.append(path)
    flush_git_add_files()
    print("Ready for commit.")