diff --git a/Lib/json/tool.py b/Lib/json/tool.py --- a/Lib/json/tool.py +++ b/Lib/json/tool.py @@ -13,25 +13,27 @@ Usage:: import sys import json def main(): if len(sys.argv) == 1: infile = sys.stdin outfile = sys.stdout elif len(sys.argv) == 2: - infile = open(sys.argv[1], 'rb') + infile = open(sys.argv[1], 'r') outfile = sys.stdout elif len(sys.argv) == 3: - infile = open(sys.argv[1], 'rb') - outfile = open(sys.argv[2], 'wb') + infile = open(sys.argv[1], 'r') + outfile = open(sys.argv[2], 'w') else: raise SystemExit(sys.argv[0] + " [infile [outfile]]") - try: - obj = json.load(infile) - except ValueError as e: - raise SystemExit(e) - json.dump(obj, outfile, sort_keys=True, indent=4) - outfile.write('\n') + with infile: + try: + obj = json.load(infile) + except ValueError as e: + raise SystemExit(e) + with outfile as outfile: + json.dump(obj, outfile, sort_keys=True, indent=4) + outfile.write('\n') if __name__ == '__main__': main() diff --git a/Lib/test/json_tests/test_dump.py b/Lib/test/json_tests/test_dump.py --- a/Lib/test/json_tests/test_dump.py +++ b/Lib/test/json_tests/test_dump.py @@ -1,11 +1,15 @@ +import subprocess +import sys +import tempfile + from io import StringIO + from test.json_tests import PyTest, CTest - from test.support import bigmemtest, _1G class TestDump: def test_dump(self): sio = StringIO() self.json.dump({}, sio) self.assertEqual(sio.getvalue(), '{}') @@ -23,16 +27,34 @@ class TestDump: # Issue 16228: Crash on encoding resized list def test_encode_mutated(self): a = [object()] * 10 def crasher(obj): del a[-1] self.assertEqual(self.dumps(a, default=crasher), '[null, null, null, null, null]') + # see issue 16549 + def test_cmd_line_dump(self): + json = '{"distutils":["Doc/distutils", "Lib/distutils",' \ + '"Lib/test/test_distutils.py"], "json":["Doc/library/json.rst",' \ + '"Lib/json", "Lib/test/json_tests", "Lib/test/test_json.py"]}' + expected = b'{\n "distutils": [\n "Doc/distutils", \n ' \ + b'"Lib/distutils", \n "Lib/test/test_distutils.py"\n ],' \ + b' \n "json": [\n "Doc/library/json.rst", \n ' \ + b'"Lib/json", \n "Lib/test/json_tests", \n ' \ + b'"Lib/test/test_json.py"\n ]\n}\n' + with tempfile.NamedTemporaryFile("w+") as stdin: + stdin.write(json) + stdin.flush() + with subprocess.Popen( + (sys.executable, '-m', 'json.tool', stdin.name), + stdin=stdin, stdout=subprocess.PIPE) as proc: + stdout, stderr = proc.communicate() + self.assertEqual(stdout.rstrip(), expected.rstrip()) class TestPyDump(TestDump, PyTest): pass class TestCDump(TestDump, CTest): # The size requirement here is hopefully over-estimated (actual # memory consumption depending on implementation details, and also # system memory management, since this may allocate a lot of