# Buggy code
def _edit_file_helper(self, filename, existing_data=None, force_save=False):
    # Create a tempfile
    _, tmp_path = tempfile.mkstemp()

    if existing_data:
        self.write_data(existing_data, tmp_path, shred=False)

    # drop the user into an editor on the tmp file
    try:
        call(self._editor_shell_command(tmp_path))
    except:
        # whatever happens, destroy the decrypted file
        self._shred_file(tmp_path)
        raise

    tmpdata = self.read_data(tmp_path)

    # Do nothing if the content has not changed
    if existing_data == tmpdata and not force_save:
        self._shred_file(tmp_path)
        return

    # encrypt new data and write out to tmp
    # An existing vaultfile will always be UTF-8,
    # so decode to unicode here
    enc_data = self.vault.encrypt(tmpdata.decode())
    self.write_data(enc_data, tmp_path)

    # shuffle tmp file into place
    self.shuffle_files(tmp_path, filename)


# Traceback (UnicodeDecodeError)
[fedora-23:ansible (devel % u=)]$ cat example_fail.yml

---
- name: 'A play with unicode: ¢ £ ¤ ¥'
hosts: localhost
connection: local
vars:
test_var: 'Ī ī Ĭ ĭ Į į İ ı Ĳ ĳ Ĵ ĵ Ķ ķ ĸ Ĺ ĺ Ļ ļ Ľ ľ Ŀ ŀ Ł ł Ń ń Ņ ņ Ň ň ŉ Ŋ ŋ Ō ō Ŏ ŏ Ő ő Œ'
hostnames:
- 'host-ϬϭϮϯϰ'
- 'host-fóöbär'
- 'host-ΙΚΛΜΝΞ'
- 'host-στυφχψ'
- 'host-ϬϭϮϯϰϱ'

[fedora-23:ansible (devel % u=)]$ ansible-vault encrypt example_fail.yml
Vault password:
Encryption successful
[fedora-23:ansible (devel % u=)]$ ansible-vault -vvv edit example_fail.yml
Using /home/adrian/.ansible.cfg as config file
Vault password:

#  NOTE: when in the interactive editor, edit the file in some way so that it is different so it will be reencrypted

ERROR! Unexpected Exception: 'ascii' codec can't decode byte 0xc2 in position 34: ordinal not in range(128)
the full traceback was:

Traceback (most recent call last):
File "/home/adrian/src/ansible/bin/ansible-vault", line 103, in <module>
exit_code = cli.run()
File "/home/adrian/src/ansible/lib/ansible/cli/vault.py", line 123, in run
self.execute()
File "/home/adrian/src/ansible/lib/ansible/cli/__init__.py", line 147, in execute
fn()
File "/home/adrian/src/ansible/lib/ansible/cli/vault.py", line 159, in execute_edit
self.editor.edit_file(f)
File "/home/adrian/src/ansible/lib/ansible/parsing/vault/__init__.py", line 464, in edit_file
self._edit_file_helper(filename, existing_data=plaintext, force_save=False)
File "/home/adrian/src/ansible/lib/ansible/parsing/vault/__init__.py", line 411, in _edit_file_helper
enc_data = self.vault.encrypt(tmpdata.decode())
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position 34: ordinal not in range(128)

# Fixed code
def _edit_file_helper(self, filename, existing_data=None, force_save=False):
    # Create a tempfile
    _, tmp_path = tempfile.mkstemp()

    if existing_data:
        self.write_data(existing_data, tmp_path, shred=False)

    # drop the user into an editor on the tmp file
    try:
        call(self._editor_shell_command(tmp_path))
    except:
        # whatever happens, destroy the decrypted file
        self._shred_file(tmp_path)
        raise

    b_tmpdata = self.read_data(tmp_path)

    # Do nothing if the content has not changed
    if existing_data == b_tmpdata and not force_save:
        self._shred_file(tmp_path)
        return

    # encrypt new data and write out to tmp
    # An existing vaultfile will always be UTF-8,
    # so decode to unicode here
    b_ciphertext = self.vault.encrypt(b_tmpdata)
    self.write_data(b_ciphertext, tmp_path)

    # shuffle tmp file into place
    self.shuffle_files(tmp_path, filename)