1. Kirill Simonov
  2. pyyaml
  3. Issues
Issue #9 new

Ignore duplicate keys and send warning or raise exception depending on mode

Jeff Kowalczyk
created an issue

pyyaml-3.10 accepts duplicate mapping keys silently, apparently with latest key wins behaviour:

>>> dupkeys_yaml = '''
... a: 1
... b: 2
... c: 3
... a: 4
... '''
>>> yaml.load(dupkeys_yaml)
{'a': 4, 'b': 2, 'c': 3}

The YAML spec recommends processors "continue, ignoring the second key: value pair and issuing an appropriate warning. "

http://yaml.org/spec/1.1/#id932806

I would like to use pyyaml load() in a mode that raises exceptions on duplicate keys. Other users may prefer a warning (configurable to be silenced) and ignoring of second keys, as recommended by the spec.

Potential for breaking change

A majority of users and dependent software may prefer or rely on the current behavior, so that should remain an option to load(). Since the default is not in agreement with the spec, perhaps it should not remain the default behavior, after a deprecation period.

This issue has been raised previously in the earlier pyyaml trac instance: http://pyyaml.org/ticket/128 , reference material was obtained from there.

Comments (4)

  1. Jeff Kowalczyk reporter

    Another call to address this. I just concluded a long bug-hunting session where the self-inflicted problem was duplicate keys in emitted YAML, with the later duplicate key carrying an incorrect subkey value.

    I would like to have an option in the parser to raise an exception on duplicate keys, complementing a change to follow the spec recommendation to ignore the second key: value pair and raise a warning.

  2. Parakleta

    Since the authors seem to have no interest in fixing this issue, for people who need this functionality the outcome can be achieved without modifying the pyyaml library itself by using the add_constructor method. The simplest option is to copy the construct_mapping function from constructor.py:120 into your project, modify the behaviour to suit, and then call yaml.add_constructor(yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG, my_mapping_func)

  3. Log in to comment