[Python-checkins] bpo-45644: Make json.tool read infile before writing to outfile (GH-29273) (GH-29445)
ambv
webhook-mailer at python.org
Sat Nov 6 14:01:27 EDT 2021
https://github.com/python/cpython/commit/6603f6b5bdf0ed164bad4eb432619da2e95fb518
commit: 6603f6b5bdf0ed164bad4eb432619da2e95fb518
branch: 3.10
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: ambv <lukasz at langa.pl>
date: 2021-11-06T19:01:17+01:00
summary:
bpo-45644: Make json.tool read infile before writing to outfile (GH-29273) (GH-29445)
so that
$ python -m json.tool foo.json foo.json
doesn't result in an empty foo.json.
Co-authored-by: Łukasz Langa <lukasz at langa.pl>
(cherry picked from commit 815dad42d53fc40a6dc057e067f4a8a885c3b858)
Co-authored-by: Chris Wesseling <chris.wesseling at protonmail.com>
files:
A Misc/NEWS.d/next/Library/2021-11-06-17-47-46.bpo-45644.ZMqHD_.rst
M Lib/json/tool.py
M Lib/test/test_json/test_tool.py
diff --git a/Lib/json/tool.py b/Lib/json/tool.py
index 5dee0a744b2a9..0490b8c0be11d 100644
--- a/Lib/json/tool.py
+++ b/Lib/json/tool.py
@@ -13,6 +13,7 @@
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 0386690cad95b..1d7fca6efb1cc 100644
--- a/Lib/test/test_json/test_tool.py
+++ b/Lib/test/test_json/test_tool.py
@@ -131,6 +131,15 @@ def test_infile_outfile(self):
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 0000000000000..2cf4eae02c449
--- /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.
More information about the Python-checkins
mailing list