diff options
author | Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> | 2021-11-06 11:01:44 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-11-06 19:01:44 +0100 |
commit | a932631890d148444e5f9b09f4b57305475d6386 (patch) | |
tree | 64028590f7c733b8b7cdf88b63fade28a5782e41 | |
parent | 5017306c8732b3ceda878db13088f8c2cf0c5e71 (diff) | |
download | cpython-git-a932631890d148444e5f9b09f4b57305475d6386.tar.gz |
bpo-45644: Make json.tool read infile before writing to outfile (GH-29273) (GH-29446)
so that
$ python -m json.tool foo.json foo.json
doesn't result in an empty foo.json.
Co-authored-by: Ćukasz Langa <lukasz@langa.pl>
(cherry picked from commit 815dad42d53fc40a6dc057e067f4a8a885c3b858)
Co-authored-by: Chris Wesseling <chris.wesseling@protonmail.com>
-rw-r--r-- | Lib/json/tool.py | 21 | ||||
-rw-r--r-- | Lib/test/test_json/test_tool.py | 9 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Library/2021-11-06-17-47-46.bpo-45644.ZMqHD_.rst | 3 |
3 files changed, 26 insertions, 7 deletions
diff --git a/Lib/json/tool.py b/Lib/json/tool.py index 5dee0a744b..0490b8c0be 100644 --- a/Lib/json/tool.py +++ b/Lib/json/tool.py @@ -13,6 +13,7 @@ Usage:: import argparse import json import sys +from pathlib import Path def main(): @@ -25,9 +26,9 @@ def main(): 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"), + type=Path, help='write the output of infile to outfile', - default=sys.stdout) + default=None) parser.add_argument('--sort-keys', action='store_true', default=False, help='sort the output of dictionaries alphabetically by key') parser.add_argument('--no-ensure-ascii', dest='ensure_ascii', action='store_false', @@ -58,15 +59,21 @@ def main(): dump_args['indent'] = None dump_args['separators'] = ',', ':' - with options.infile as infile, options.outfile as outfile: + with options.infile as infile: try: if options.json_lines: objs = (json.loads(line) for line in infile) else: - objs = (json.load(infile), ) - for obj in objs: - json.dump(obj, outfile, **dump_args) - outfile.write('\n') + objs = (json.load(infile),) + + if options.outfile is None: + out = sys.stdout + else: + out = options.outfile.open('w', encoding='utf-8') + with out as outfile: + for obj in objs: + 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 fc2a7a4fca..d441bb15a7 100644 --- a/Lib/test/test_json/test_tool.py +++ b/Lib/test/test_json/test_tool.py @@ -130,6 +130,15 @@ class TestTool(unittest.TestCase): self.assertEqual(out, b'') self.assertEqual(err, b'') + def test_writing_in_place(self): + infile = self._create_infile() + rc, out, err = assert_python_ok('-m', 'json.tool', infile, infile) + with open(infile, "r", encoding="utf-8") as fp: + self.assertEqual(fp.read(), self.expect) + self.assertEqual(rc, 0) + self.assertEqual(out, b'') + self.assertEqual(err, b'') + def test_jsonlines(self): args = sys.executable, '-m', 'json.tool', '--json-lines' process = subprocess.run(args, input=self.jsonlines_raw, capture_output=True, text=True, check=True) diff --git a/Misc/NEWS.d/next/Library/2021-11-06-17-47-46.bpo-45644.ZMqHD_.rst b/Misc/NEWS.d/next/Library/2021-11-06-17-47-46.bpo-45644.ZMqHD_.rst new file mode 100644 index 0000000000..2cf4eae02c --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-11-06-17-47-46.bpo-45644.ZMqHD_.rst @@ -0,0 +1,3 @@ +In-place JSON file formatting using ``python3 -m json.tool infile infile`` +now works correctly, previously it left the file empty. Patch by Chris +Wesseling. |