summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnthon van der Neut <anthon@mnt.org>2018-12-05 21:10:17 +0100
committerAnthon van der Neut <anthon@mnt.org>2018-12-05 21:10:17 +0100
commit702a0ce64bb990e5c442f8d3dcaf05c72a3ff255 (patch)
treedd0e0b4f05f969a2e8f02bd7023a9cd42b9e5ee9
parent1e55c0f897e2255bfb0c28f35d49401f086c1e38 (diff)
downloadruamel.yaml-702a0ce64bb990e5c442f8d3dcaf05c72a3ff255.tar.gz
fix value taken with duplicate keys
-rw-r--r--_doc/api.ryd3
-rw-r--r--constructor.py57
2 files changed, 34 insertions, 26 deletions
diff --git a/_doc/api.ryd b/_doc/api.ryd
index 9eb7c6f..1b4208d 100644
--- a/_doc/api.ryd
+++ b/_doc/api.ryd
@@ -115,6 +115,9 @@ yaml.load(stream)
In the old API this is a warning starting with 0.15.2 and an error in
0.16.0.
+When a duplicate key is found it and its value are discarded, as should be done
+according to the `YAML 1.1 specification <http://yaml.org/spec/1.1/#id932806>`__.
+
Dumping a multi-documents YAML stream
+++++++++++++++++++++++++++++++++++++
diff --git a/constructor.py b/constructor.py
index 09c55dd..2d3250a 100644
--- a/constructor.py
+++ b/constructor.py
@@ -241,13 +241,16 @@ class BaseConstructor(object):
value = self.construct_object(value_node, deep=deep)
if check:
- self.check_mapping_key(node, key_node, mapping, key, value)
- mapping[key] = value
+ if self.check_mapping_key(node, key_node, mapping, key, value):
+ mapping[key] = value
+ else:
+ mapping[key] = value
total_mapping.update(mapping)
return total_mapping
def check_mapping_key(self, node, key_node, mapping, key, value):
- # type: (Any, Any, Any, Any, Any) -> None
+ # type: (Any, Any, Any, Any, Any) -> bool
+ """return True if key is unique"""
if key in mapping:
if not self.allow_duplicate_keys:
mk = mapping.get(key)
@@ -277,6 +280,8 @@ class BaseConstructor(object):
warnings.warn(DuplicateKeyFutureWarning(*args))
else:
raise DuplicateKeyError(*args)
+ return False
+ return True
def check_set_key(self, node, key_node, setting, key):
# type: (Any, Any, Any, Any, Any) -> None
@@ -1411,31 +1416,31 @@ class RoundTripConstructor(SafeConstructor):
key_node.start_mark,
)
value = self.construct_object(value_node, deep=deep)
- self.check_mapping_key(node, key_node, maptyp, key, value)
+ if self.check_mapping_key(node, key_node, maptyp, key, value):
- if key_node.comment and len(key_node.comment) > 4 and key_node.comment[4]:
- if last_value is None:
- key_node.comment[0] = key_node.comment.pop(4)
- maptyp._yaml_add_comment(key_node.comment, value=last_key)
- else:
- key_node.comment[2] = key_node.comment.pop(4)
+ if key_node.comment and len(key_node.comment) > 4 and key_node.comment[4]:
+ if last_value is None:
+ key_node.comment[0] = key_node.comment.pop(4)
+ maptyp._yaml_add_comment(key_node.comment, value=last_key)
+ else:
+ key_node.comment[2] = key_node.comment.pop(4)
+ maptyp._yaml_add_comment(key_node.comment, key=key)
+ key_node.comment = None
+ if key_node.comment:
maptyp._yaml_add_comment(key_node.comment, key=key)
- key_node.comment = None
- if key_node.comment:
- maptyp._yaml_add_comment(key_node.comment, key=key)
- if value_node.comment:
- maptyp._yaml_add_comment(value_node.comment, value=key)
- maptyp._yaml_set_kv_line_col(
- key,
- [
- key_node.start_mark.line,
- key_node.start_mark.column,
- value_node.start_mark.line,
- value_node.start_mark.column,
- ],
- )
- maptyp[key] = value
- last_key, last_value = key, value # could use indexing
+ if value_node.comment:
+ maptyp._yaml_add_comment(value_node.comment, value=key)
+ maptyp._yaml_set_kv_line_col(
+ key,
+ [
+ key_node.start_mark.line,
+ key_node.start_mark.column,
+ value_node.start_mark.line,
+ value_node.start_mark.column,
+ ],
+ )
+ maptyp[key] = value
+ last_key, last_value = key, value # could use indexing
# do this last, or <<: before a key will prevent insertion in instances
# of collections.OrderedDict (as they have no __contains__
if merge_map: