Skip to content

Commit 190e778

Browse files
committed
Merge duplicate keys in JSON.
### Description I would love to make this an error, but we have had a duplicate key in `targets.json` for a while now. Instead, we're merging in a semi-smart way. This will allow you to have things like `"target.features_add"` twice, and both will take affect. ### Pull request type [x] Fix [ ] Refactor [ ] Target update [ ] Functionality change [ ] Docs update [ ] Test update [ ] Breaking change
1 parent 41bffe1 commit 190e778

File tree

1 file changed

+25
-5
lines changed

1 file changed

+25
-5
lines changed

tools/utils.py

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,24 @@ def check_required_modules(required_modules, verbose=True):
359359
else:
360360
return True
361361

362+
363+
def _ordered_dict_collapse_dups(pair_list):
364+
to_ret = OrderedDict()
365+
for key, value in pair_list:
366+
if key in to_ret:
367+
if isinstance(to_ret[key], dict):
368+
to_ret[key].update(value)
369+
elif isinstance(to_ret[key], list):
370+
to_ret[key].extend(value)
371+
else:
372+
raise ValueError(
373+
"Key %s found twice and is not mergeable" % key
374+
)
375+
else:
376+
to_ret[key] = value
377+
return to_ret
378+
379+
362380
def json_file_to_dict(fname):
363381
""" Read a JSON file and return its Python representation, transforming all
364382
the strings from Unicode to ASCII. The order of keys in the JSON file is
@@ -368,11 +386,13 @@ def json_file_to_dict(fname):
368386
fname - the name of the file to parse
369387
"""
370388
try:
371-
with io.open(fname, encoding='ascii',
372-
errors='ignore') as file_obj:
373-
return json.load(file_obj, object_pairs_hook=OrderedDict)
374-
except (ValueError, IOError):
375-
sys.stderr.write("Error parsing '%s':\n" % fname)
389+
with io.open(fname, encoding='ascii',
390+
errors='ignore') as file_obj:
391+
return json.load(
392+
file_obj, object_pairs_hook=_ordered_dict_collapse_dups
393+
)
394+
except (ValueError, IOError) as e:
395+
sys.stderr.write("Error parsing '%s': %s\n" % (fname, e))
376396
raise
377397

378398
# Wowza, double closure

0 commit comments

Comments
 (0)