diff --git a/Lib/json/tool.py b/Lib/json/tool.py index 0490b8c0be11df..db092e3260e59c 100644 --- a/Lib/json/tool.py +++ b/Lib/json/tool.py @@ -15,6 +15,7 @@ import sys from pathlib import Path +_SENTINEL = object() def main(): prog = 'python -m json.tool' @@ -62,7 +63,7 @@ def main(): with options.infile as infile: try: if options.json_lines: - objs = (json.loads(line) for line in infile) + objs = (json.loads(line) if line.strip() else _SENTINEL for line in infile) else: objs = (json.load(infile),) @@ -72,7 +73,8 @@ def main(): out = options.outfile.open('w', encoding='utf-8') with out as outfile: for obj in objs: - json.dump(obj, outfile, **dump_args) + if obj is not _SENTINEL: + json.dump(obj, outfile, **dump_args) outfile.write('\n') except ValueError as e: raise SystemExit(e) diff --git a/Lib/test/test_json/test_tool.py b/Lib/test/test_json/test_tool.py index 2b63810d53981e..33fa42e231b8be 100644 --- a/Lib/test/test_json/test_tool.py +++ b/Lib/test/test_json/test_tool.py @@ -86,6 +86,24 @@ class TestTool(unittest.TestCase): } """) + jsonlines_emptylines_raw = textwrap.dedent("""\ + {"foo":1} + + {"bar":2} + + """) + + jsonlines_emptylines_expect = textwrap.dedent("""\ + { + "foo": 1 + } + + { + "bar": 2 + } + + """) + def test_stdin_stdout(self): args = sys.executable, '-m', 'json.tool' process = subprocess.run(args, input=self.data, capture_output=True, text=True, check=True) @@ -147,6 +165,12 @@ def test_jsonlines(self): self.assertEqual(process.stdout, self.jsonlines_expect) self.assertEqual(process.stderr, '') + def test_jsonlines_emptylines(self): + args = sys.executable, '-m', 'json.tool', '--json-lines' + process = subprocess.run(args, input=self.jsonlines_emptylines_raw, capture_output=True, text=True, check=True) + self.assertEqual(process.stdout, self.jsonlines_emptylines_expect) + self.assertEqual(process.stderr, '') + def test_help_flag(self): rc, out, err = assert_python_ok('-m', 'json.tool', '-h') self.assertEqual(rc, 0) diff --git a/Misc/NEWS.d/next/Library/2021-11-30-07-15-32.bpo-45929.EeKtTK.rst b/Misc/NEWS.d/next/Library/2021-11-30-07-15-32.bpo-45929.EeKtTK.rst new file mode 100644 index 00000000000000..752e7e56e6548e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-11-30-07-15-32.bpo-45929.EeKtTK.rst @@ -0,0 +1 @@ +Let json.tool --json-lines handle empty rows