diff --git a/Doc/library/json.rst b/Doc/library/json.rst --- a/Doc/library/json.rst +++ b/Doc/library/json.rst @@ -608,11 +608,17 @@ Command line options If *infile* is not specified, read from :attr:`sys.stdin`. .. cmdoption:: outfile Write the output of the *infile* to the given *outfile*. Otherwise, write it to :attr:`sys.stdout`. +.. cmdoption:: --unsorted + + Do not sort the output of dictionaries by their key. + + .. versionadded:: 3.5 + .. cmdoption:: -h, --help Show the help message. diff --git a/Lib/json/tool.py b/Lib/json/tool.py --- a/Lib/json/tool.py +++ b/Lib/json/tool.py @@ -19,24 +19,28 @@ def main(): prog = 'python -m json.tool' description = ('A simple command line interface for json module ' 'to validate and pretty-print JSON objects.') parser = argparse.ArgumentParser(prog=prog, description=description) parser.add_argument('infile', nargs='?', type=argparse.FileType(), help='a JSON file to be validated or pretty-printed') parser.add_argument('outfile', nargs='?', type=argparse.FileType('w'), help='write the output of infile to outfile') + parser.add_argument('--unsorted', dest='sort_keys', action='store_true', + default=False, help='do not sort the output of ' + 'dictionaries by their key.') options = parser.parse_args() infile = options.infile or sys.stdin outfile = options.outfile or sys.stdout + sort_keys = not options.sort_keys with infile: try: obj = json.load(infile) except ValueError as e: raise SystemExit(e) with outfile: - json.dump(obj, outfile, sort_keys=True, indent=4) + json.dump(obj, outfile, sort_keys=sort_keys, indent=4) outfile.write('\n') if __name__ == '__main__': main() diff --git a/Lib/test/test_json/test_tool.py b/Lib/test/test_json/test_tool.py --- a/Lib/test/test_json/test_tool.py +++ b/Lib/test/test_json/test_tool.py @@ -32,16 +32,38 @@ class TestTool(unittest.TestCase): }, { "field": "yes", "morefield": false } ] """) + expect_without_sort_keys = textwrap.dedent("""\ + [ + [ + "blorpie" + ], + [ + "whoops" + ], + [], + "d-shtaeou", + "d-nthiouh", + "i-vhbjkhnth", + { + "nifty": 87 + }, + { + "morefield": false, + "field": "yes" + } + ] + """) + def test_stdin_stdout(self): with subprocess.Popen( (sys.executable, '-m', 'json.tool'), stdin=subprocess.PIPE, stdout=subprocess.PIPE) as proc: out, err = proc.communicate(self.data.encode()) self.assertEqual(out.splitlines(), self.expect.encode().splitlines()) self.assertEqual(err, None) @@ -70,8 +92,20 @@ class TestTool(unittest.TestCase): self.assertEqual(out, b'') self.assertEqual(err, b'') def test_help_flag(self): rc, out, err = assert_python_ok('-m', 'json.tool', '-h') self.assertEqual(rc, 0) self.assertTrue(out.startswith(b'usage: ')) self.assertEqual(err, b'') + + def test_unsorted_flag(self): + infile = self._create_infile() + outfile = support.TESTFN + '_unsorted.out' + rc, out, err = assert_python_ok('-m', 'json.tool', infile, outfile, + '--unsorted') + self.addCleanup(os.remove, outfile) + with open(outfile, "r") as fp: + self.assertEqual(fp.read(), self.expect_without_sort_keys) + self.assertEqual(rc, 0) + self.assertEqual(out, b'') + self.assertEqual(err, b'')