From ffdc0807434463498a66e75fd884b8f717d54987 Mon Sep 17 00:00:00 2001 From: Yannick Koehler Date: Wed, 10 Jun 2020 11:38:27 -0400 Subject: [PATCH] Added support to import JSON include file as list --- json_include.py | 50 ++++++++++++++++++++++++++------------- test/expect/d.json | 10 ++++++++ test/expect/e.json | 25 ++++++++++++++++++++ test/json_include_test.py | 4 ++-- test/source/d.json | 15 ++++++++++++ test/source/e.json | 13 ++++++++++ 6 files changed, 99 insertions(+), 18 deletions(-) create mode 100644 test/expect/d.json create mode 100644 test/expect/e.json create mode 100644 test/source/d.json create mode 100644 test/source/e.json diff --git a/json_include.py b/json_include.py index a5d3751..ce5c28a 100644 --- a/json_include.py +++ b/json_include.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # coding: utf-8 import os @@ -23,32 +23,54 @@ def read_file(filepath): def get_include_name(value): - if isinstance(value, basestring): + if isinstance(value, str): rv = INCLUDE_VALUE_PATTERN.search(value) if rv: return rv.groups()[0] return None +def is_include(o): + return set(o) == set([INCLUDE_KEY]) + + +def cache_include(include_name, dirpath): + if include_name: + if include_name not in _included_cache: + _included_cache[include_name] = parse_json_include(dirpath, include_name, True) + + def walk_through_to_include(o, dirpath): if isinstance(o, dict): is_include_exp = False - if set(o) == set([INCLUDE_KEY]): - include_name = get_include_name(o.values()[0]) - if include_name: - is_include_exp = True - o.clear() - if include_name not in _included_cache: - _included_cache[include_name] = parse_json_include(dirpath, include_name, True) - o.update(_included_cache[include_name]) + if is_include(o): + include_name = get_include_name(list(o.values())[0]) + cache_include(include_name, dirpath) + o.clear() + o.update(_included_cache[include_name]) + is_include_exp = True if is_include_exp: return - for k, v in o.iteritems(): + for k, v in o.items(): if isinstance(v, OBJECT_TYPES): walk_through_to_include(v, dirpath) elif isinstance(o, list): + is_include_exp = False + if len(o) == 1 and isinstance(o[0], dict): + i = o[0] + if is_include(i): + include_name = get_include_name(list(i.values())[0]) + cache_include(include_name, dirpath) + if isinstance(_included_cache[include_name], list): + is_include_exp = True + o.clear() + o.extend(_included_cache[include_name]) + + if is_include_exp: + return + for i in o: if isinstance(i, OBJECT_TYPES): walk_through_to_include(i, dirpath) @@ -59,10 +81,6 @@ def parse_json_include(dirpath, filename, is_include=False): json_str = read_file(filepath) d = json.loads(json_str, object_pairs_hook=OrderedDict) - if is_include: - assert isinstance(d, dict),\ - 'The JSON file being included should always be a dict rather than a list' - walk_through_to_include(d, dirpath) return d @@ -113,7 +131,7 @@ def main(): args = parser.parse_args() - print build_json_include(args.dirpath, args.filename) + print (build_json_include(args.dirpath, args.filename)) if __name__ == '__main__': diff --git a/test/expect/d.json b/test/expect/d.json new file mode 100644 index 0000000..4bbadad --- /dev/null +++ b/test/expect/d.json @@ -0,0 +1,10 @@ +{ + "aa": { + "a0": 1, + "a1": "one" + }, + "b0": { + "value": "a b0 value" + }, + "b1": true +} diff --git a/test/expect/e.json b/test/expect/e.json new file mode 100644 index 0000000..63af061 --- /dev/null +++ b/test/expect/e.json @@ -0,0 +1,25 @@ +{ + "c0": { + "value": "a c0 value", + "aaa": { + "a0": 1, + "a1": "one" + } + }, + "bb": [ + { + "aa": { + "a0": 1, + "a1": "one" + } + }, + { + "b0": { + "value": "a b0 value" + } + }, + { + "b1": true + } + ] +} diff --git a/test/json_include_test.py b/test/json_include_test.py index ae03600..9f7e92c 100644 --- a/test/json_include_test.py +++ b/test/json_include_test.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # coding: utf-8 import sys @@ -28,5 +28,5 @@ def test_build_json_include(): def run_build_json_include(dirpath, i): rv = build_json_include(dirpath, i) expect = read_file(os.path.join(_path('expect'), i)) - print rv + print(rv) assert rv.strip() == expect.strip() diff --git a/test/source/d.json b/test/source/d.json new file mode 100644 index 0000000..8b6de3f --- /dev/null +++ b/test/source/d.json @@ -0,0 +1,15 @@ +[ + { + "aa": { + "...": "" + } + }, + { + "b0": { + "value": "a b0 value" + } + }, + { + "b1": true + } +] diff --git a/test/source/e.json b/test/source/e.json new file mode 100644 index 0000000..5387a6e --- /dev/null +++ b/test/source/e.json @@ -0,0 +1,13 @@ +{ + "c0": { + "value": "a c0 value", + "aaa": { + "...": "" + } + }, + "bb": [ + { + "...": "" + } + ] +}