From e12ddb1bd4d140edce8cb7a101282d46781990f0 Mon Sep 17 00:00:00 2001 From: Spencer Young Date: Wed, 9 Dec 2020 02:06:47 -0800 Subject: [PATCH 1/9] better error message --- json5/dumper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/json5/dumper.py b/json5/dumper.py index ee2b340..1915477 100644 --- a/json5/dumper.py +++ b/json5/dumper.py @@ -178,7 +178,7 @@ def process_leading_wsc(self, node): @singledispatchmethod def dump(self, node): - raise NotImplementedError('foo') + raise NotImplementedError(f'Cannot dump node of type {type(node)}') to_json = dump.register From 67bcea36666e0027f6851231c6af25e26f83afec Mon Sep 17 00:00:00 2001 From: Spencer Young Date: Wed, 9 Dec 2020 02:07:09 -0800 Subject: [PATCH 2/9] bugfix: pass keyword args from load -> loads --- json5/loader.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/json5/loader.py b/json5/loader.py index 9dd0bde..5de11c1 100644 --- a/json5/loader.py +++ b/json5/loader.py @@ -30,7 +30,7 @@ def load(f, **kwargs): :return: """ text = f.read() - return loads(text) + return loads(text, **kwargs) def loads(s, *args, loader=None, **kwargs): """ From bacc90bebc20d14830f2c4c6fdb347004662eeab Mon Sep 17 00:00:00 2001 From: Spencer Young Date: Wed, 9 Dec 2020 02:07:20 -0800 Subject: [PATCH 3/9] feature: json5.tool --- json5/tool.py | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 json5/tool.py diff --git a/json5/tool.py b/json5/tool.py new file mode 100644 index 0000000..946f44b --- /dev/null +++ b/json5/tool.py @@ -0,0 +1,47 @@ +import argparse +from json5 import loads, dump, load +from json5.loader import ModelLoader +from json5.dumper import ModelDumper +import sys + + +def main(): + prog = 'python -m json5.tool' + description = ('Command line interface for the json5 module ' + 'analogous to the json.tool CLI.') + parser = argparse.ArgumentParser(prog=prog, description=description) + parser.add_argument('infile', nargs='?', + type=argparse.FileType(encoding="utf-8"), + help='a JSON file to be validated or pretty-printed', + default=sys.stdin) + parser.add_argument('outfile', nargs='?', + type=argparse.FileType('w', encoding="utf-8"), + help='write the output of infile to outfile', + default=sys.stdout) + parser.add_argument('--json-lines', action='store_true', default=False, + help='parse input using the JSON Lines format. ' + 'Use with --no-indent or --compact to produce valid JSON Lines output.') + options = parser.parse_args() + + dump_args = { + 'dumper': ModelDumper() + } + + with options.infile as infile, options.outfile as outfile: + try: + if options.json_lines: + objs = (loads(line, loader=ModelLoader()) for line in infile) + else: + objs = (load(infile, loader=ModelLoader()), ) + for obj in objs: + dump(obj, outfile, **dump_args) + outfile.write('\n') + except ValueError as e: + raise SystemExit(e) + + +if __name__ == '__main__': + try: + main() + except BrokenPipeError as exc: + sys.exit(exc.errno) \ No newline at end of file From bd09374ecbf4cdad8e0986e16176d4f9fc88d292 Mon Sep 17 00:00:00 2001 From: Spencer Young Date: Wed, 9 Dec 2020 02:09:11 -0800 Subject: [PATCH 4/9] add json5.tool to readme --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 906b0fa..6663754 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,12 @@ comment that can span lines /* {"foo": "bar", "bacon": "eggs"} ``` +You can also use `json5.tool` for validating json. + +``` +python3 -m json5.tool < myfile.json5 +``` + See also the [full documentation](https://json-five.readthedocs.io/en/latest/) ## Key features From edfe2e7135877a6b49e90136f4dc51d37e3e2d4d Mon Sep 17 00:00:00 2001 From: Spencer Young Date: Wed, 9 Dec 2020 02:09:55 -0800 Subject: [PATCH 5/9] v0.7.5 :package: --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index e873b84..37379a6 100644 --- a/setup.py +++ b/setup.py @@ -6,7 +6,7 @@ setup( name='json-five', - version='0.6.5', + version='0.7.5', packages=['json5'], url='https://github.com/spyoungtech/json-five', license='Apache', From df98bcbe6c8d9a159d0c0e345f50dcce3ff2416c Mon Sep 17 00:00:00 2001 From: Spencer Young Date: Wed, 9 Dec 2020 02:29:26 -0800 Subject: [PATCH 6/9] add tests --- tests/test_json_tool.py | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 tests/test_json_tool.py diff --git a/tests/test_json_tool.py b/tests/test_json_tool.py new file mode 100644 index 0000000..2efa187 --- /dev/null +++ b/tests/test_json_tool.py @@ -0,0 +1,29 @@ +import subprocess +import pytest +import io +@pytest.mark.parametrize('json_string', [ +"""{"foo":"bar"}""", +"""{"foo": "bar"}""", +"""{"foo":"bar","bacon":"eggs"}""", +"""{"foo": "bar", "bacon" : "eggs"}""", +"""["foo","bar","baz"]""", +"""[ "foo", "bar" , "baz" ]""", +"""{"foo":\n "bar"\n}""", +"""{"foo": {"bacon": "eggs"}}""", +""" {"foo":"bar"}""", +"""{"foo": "bar"} """, +"""{'foo': 'bar'}""", +"""{"foo": 'bar'}""", +"""{"foo": "bar",}""", +"""["foo","bar", "baz",]""", +"""["foo", "bar", "baz", ]""", +"""["foo", "bar", "baz" ,]""", +"""[["foo"], ["foo","bar"], "baz"]""", +"""{unquoted: "foo"}""", +"""{unquoted: "foo"}""", +"""["foo"]""", +"""["foo" , ]""", +]) +def test_tool(json_string): + r = subprocess.run(['python3', '-m', 'json5.tool'], text=True, input=json_string, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + assert r.stdout[:-1] == json_string From 9562f0b30b7a3268dd6f0308e7ed70ad4afaf622 Mon Sep 17 00:00:00 2001 From: Spencer Young Date: Wed, 9 Dec 2020 02:29:39 -0800 Subject: [PATCH 7/9] help text cleanup --- json5/tool.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/json5/tool.py b/json5/tool.py index 946f44b..b2e72a4 100644 --- a/json5/tool.py +++ b/json5/tool.py @@ -12,15 +12,14 @@ def main(): parser = argparse.ArgumentParser(prog=prog, description=description) parser.add_argument('infile', nargs='?', type=argparse.FileType(encoding="utf-8"), - help='a JSON file to be validated or pretty-printed', + help='a JSON file to be validated', default=sys.stdin) parser.add_argument('outfile', nargs='?', type=argparse.FileType('w', encoding="utf-8"), help='write the output of infile to outfile', default=sys.stdout) parser.add_argument('--json-lines', action='store_true', default=False, - help='parse input using the JSON Lines format. ' - 'Use with --no-indent or --compact to produce valid JSON Lines output.') + help='parse input using the JSON Lines format.') options = parser.parse_args() dump_args = { From 1e52cf6198e0a45d5176f505371cba4e7e711e5a Mon Sep 17 00:00:00 2001 From: Spencer Young Date: Wed, 9 Dec 2020 02:30:02 -0800 Subject: [PATCH 8/9] clarify json5.tool state --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 6663754..d6221cf 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,8 @@ You can also use `json5.tool` for validating json. ``` python3 -m json5.tool < myfile.json5 ``` +As of right now, there is no formatting on the output; original whitespace and comments is maintained. +In the future, pretty-printing, stripping comments, and other options may be added. See also the [full documentation](https://json-five.readthedocs.io/en/latest/) From 3be2d5118d1a8803defe9005a98781226a222615 Mon Sep 17 00:00:00 2001 From: Spencer Young Date: Wed, 9 Dec 2020 02:34:14 -0800 Subject: [PATCH 9/9] test compat for 3.6 --- tests/test_json_tool.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/test_json_tool.py b/tests/test_json_tool.py index 2efa187..17ec3d1 100644 --- a/tests/test_json_tool.py +++ b/tests/test_json_tool.py @@ -25,5 +25,11 @@ """["foo" , ]""", ]) def test_tool(json_string): - r = subprocess.run(['python3', '-m', 'json5.tool'], text=True, input=json_string, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + r = subprocess.run( + ["python3", "-m", "json5.tool"], + universal_newlines=True, + input=json_string, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + ) assert r.stdout[:-1] == json_string