From 9bd0ad6e56928a3ef300911a67441da6b2fee16f Mon Sep 17 00:00:00 2001 From: Chris Wesseling Date: Thu, 28 Oct 2021 14:47:44 +0200 Subject: [PATCH] Make json.tool soak up infile before writing to outfile So that $ python -m json.tool foo.json foo.json doens't result in an empty foo.json. --- Lib/json/tool.py | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/Lib/json/tool.py b/Lib/json/tool.py index 5dee0a744b2a99e..5859a2d3b04ca4f 100644 --- a/Lib/json/tool.py +++ b/Lib/json/tool.py @@ -13,6 +13,18 @@ import argparse import json import sys +from pathlib import Path + + +def pathtype(path): + class wrapped_fd: + 'Make stdin and stdout have open() like a `pathlib.Path`' + def __init__(self, file_descriptor): + self.fd = file_descriptor + + def open(self, *args, **kwargs): + return self.fd + return wrapped_fd(path) if path in (sys.stdin, sys.stderr) else Path(path) def main(): @@ -21,11 +33,11 @@ def main(): 'to validate and pretty-print JSON objects.') parser = argparse.ArgumentParser(prog=prog, description=description) parser.add_argument('infile', nargs='?', - type=argparse.FileType(encoding="utf-8"), + type=pathtype, 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=pathtype, help='write the output of infile to outfile', default=sys.stdout) parser.add_argument('--sort-keys', action='store_true', default=False, @@ -58,12 +70,17 @@ def main(): dump_args['indent'] = None dump_args['separators'] = ',', ':' - with options.infile as infile, options.outfile as outfile: + with options.infile.open(encoding='utf-8') as infile: try: if options.json_lines: objs = (json.loads(line) for line in infile) else: - objs = (json.load(infile), ) + objs = (json.load(infile),) + except ValueError as e: + raise SystemExit(e) + + with options.outfile.open('w', encoding='utf-8') as outfile: + try: for obj in objs: json.dump(obj, outfile, **dump_args) outfile.write('\n')