From f3127a43ba08cb4d864f64bb37c19e85cd2661b5 Mon Sep 17 00:00:00 2001 From: Jimmy Brisson Date: Tue, 23 Oct 2018 11:23:33 -0500 Subject: [PATCH] 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 --- tools/utils.py | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/tools/utils.py b/tools/utils.py index 3fcbf2d0fb..368b968a46 100644 --- a/tools/utils.py +++ b/tools/utils.py @@ -359,6 +359,24 @@ def check_required_modules(required_modules, verbose=True): else: return True + +def _ordered_dict_collapse_dups(pair_list): + to_ret = OrderedDict() + for key, value in pair_list: + if key in to_ret: + if isinstance(to_ret[key], dict): + to_ret[key].update(value) + elif isinstance(to_ret[key], list): + to_ret[key].extend(value) + else: + raise ValueError( + "Key %s found twice and is not mergeable" % key + ) + else: + to_ret[key] = value + return to_ret + + def json_file_to_dict(fname): """ Read a JSON file and return its Python representation, transforming all 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): fname - the name of the file to parse """ try: - with io.open(fname, encoding='ascii', - errors='ignore') as file_obj: - return json.load(file_obj, object_pairs_hook=OrderedDict) - except (ValueError, IOError): - sys.stderr.write("Error parsing '%s':\n" % fname) + with io.open(fname, encoding='ascii', + errors='ignore') as file_obj: + return json.load( + file_obj, object_pairs_hook=_ordered_dict_collapse_dups + ) + except (ValueError, IOError) as e: + sys.stderr.write("Error parsing '%s': %s\n" % (fname, e)) raise # Wowza, double closure