# Buggy code
def construct_mapping(self, node, deep=False):
    # Most of this is from yaml.constructor.SafeConstructor.  We replicate
    # it here so that we can warn users when they have duplicate dict keys
    # (pyyaml silently allows overwriting keys)
    if not isinstance(node, MappingNode):
        raise ConstructorError(
            None,
            None,
            "expected a mapping node, but found %s" % node.id,
            node.start_mark,
        )
    self.flatten_mapping(node)
    mapping = AnsibleMapping()

    # Add our extra information to the returned value
    mapping.ansible_pos = self._node_position_info(node)

    for key_node, value_node in node.value:
        key = self.construct_object(key_node, deep=deep)
        try:
            hash(key)
        except TypeError as exc:
            raise ConstructorError(
                "while constructing a mapping",
                node.start_mark,
                "found unacceptable key (%s)" % exc,
                key_node.start_mark,
            )

        if key in mapping:
            display.warning(
                "While constructing a mapping from {1}, line {2}, column {3}, found a duplicate dict key ({0}).  Using last defined value only.".format(
                    key, *mapping.ansible_pos
                )
            )

        value = self.construct_object(value_node, deep=deep)
        mapping[key] = value

    return mapping


# Traceback (UnicodeEncodeError)
$ ansible-playbook -i test deploy.yml -vvv
No config file found; using defaults
ERROR! Unexpected Exception: 'ascii' codec can't encode characters in position 16-24: ordinal not in range(128)
the full traceback was:

Traceback (most recent call last):
File "/opt/ansible/bin/ansible-playbook", line 86, in <module>
sys.exit(cli.run())
File "/opt/ansible/lib/ansible/cli/playbook.py", line 150, in run
results = pbex.run()
File "/opt/ansible/lib/ansible/executor/playbook_executor.py", line 79, in run
pb = Playbook.load(playbook_path, variable_manager=self._variable_manager, loader=self._loader)
File "/opt/ansible/lib/ansible/playbook/__init__.py", line 52, in load
pb._load_playbook_data(file_name=file_name, variable_manager=variable_manager)
File "/opt/ansible/lib/ansible/playbook/__init__.py", line 74, in _load_playbook_data
ds = self._loader.load_from_file(os.path.basename(file_name))
File "/opt/ansible/lib/ansible/parsing/dataloader.py", line 114, in load_from_file
parsed_data = self.load(data=file_data, file_name=file_name, show_content=show_content)
File "/opt/ansible/lib/ansible/parsing/dataloader.py", line 93, in load
new_data = self._safe_load(new_data, file_name=file_name)
File "/opt/ansible/lib/ansible/parsing/dataloader.py", line 148, in _safe_load
return loader.get_single_data()
File "/usr/local/lib/python2.7/dist-packages/yaml/constructor.py", line 39, in get_single_data
return self.construct_document(node)
File "/usr/local/lib/python2.7/dist-packages/yaml/constructor.py", line 48, in construct_document
for dummy in generator:
File "/opt/ansible/lib/ansible/parsing/yaml/constructor.py", line 41, in construct_yaml_map
value = self.construct_mapping(node)
File "/opt/ansible/lib/ansible/parsing/yaml/constructor.py", line 68, in construct_mapping
display.warning('While constructing a mapping from {1}, line {2}, column {3}, found a duplicate dict key ({0}).  Using last defined value only.'.format(key, *mapping.ansible_pos))
UnicodeEncodeError: 'ascii' codec can't encode characters in position 16-24: ordinal not in range(128)

# Fixed code
def construct_mapping(self, node, deep=False):
    # Most of this is from yaml.constructor.SafeConstructor.  We replicate
    # it here so that we can warn users when they have duplicate dict keys
    # (pyyaml silently allows overwriting keys)
    if not isinstance(node, MappingNode):
        raise ConstructorError(
            None,
            None,
            "expected a mapping node, but found %s" % node.id,
            node.start_mark,
        )
    self.flatten_mapping(node)
    mapping = AnsibleMapping()

    # Add our extra information to the returned value
    mapping.ansible_pos = self._node_position_info(node)

    for key_node, value_node in node.value:
        key = self.construct_object(key_node, deep=deep)
        try:
            hash(key)
        except TypeError as exc:
            raise ConstructorError(
                "while constructing a mapping",
                node.start_mark,
                "found unacceptable key (%s)" % exc,
                key_node.start_mark,
            )

        if key in mapping:
            display.warning(
                "While constructing a mapping from {1}, line {2}, column {3}, found a duplicate dict key ({0}).  Using last defined value only.".format(
                    key, *mapping.ansible_pos
                )
            )

        value = self.construct_object(value_node, deep=deep)
        mapping[key] = value

    return mapping