]> granicus.if.org Git - python/commitdiff
improve the command-line interface of json.tool (closes #21000)
authorBenjamin Peterson <benjamin@python.org>
Sat, 22 Mar 2014 04:17:29 +0000 (23:17 -0500)
committerBenjamin Peterson <benjamin@python.org>
Sat, 22 Mar 2014 04:17:29 +0000 (23:17 -0500)
A patch from Berker Peksag.

Doc/library/json.rst
Lib/json/tool.py
Lib/test/test_json/test_tool.py
Misc/NEWS

index 5d97ee88fc49ceb0deee9717f8210f0c140d0dcc..1d5578779272ae2788d3267a15e7023e72ea99fc 100644 (file)
@@ -104,6 +104,8 @@ Using json.tool from the shell to validate and pretty-print::
     $ echo '{1.2:3.4}' | python -mjson.tool
     Expecting property name enclosed in double quotes: line 1 column 2 (char 1)
 
+See :ref:`json-commandline` for detailed documentation.
+
 .. highlight:: python3
 
 .. note::
@@ -563,3 +565,52 @@ the last name-value pair for a given name::
    {'x': 3}
 
 The *object_pairs_hook* parameter can be used to alter this behavior.
+
+.. highlight:: bash
+
+.. _json-commandline:
+
+Command Line Interface
+----------------------
+
+The :mod:`json.tool` module provides a simple command line interface to validate
+and pretty-print JSON objects.
+
+If the optional :option:`infile` and :option:`outfile` arguments are not
+specified, :attr:`sys.stdin` and :attr:`sys.stdout` will be used respectively::
+
+    $ echo '{"json": "obj"}' | python -m json.tool
+    {
+        "json": "obj"
+    }
+    $ echo '{1.2:3.4}' | python -m json.tool
+    Expecting property name enclosed in double quotes: line 1 column 2 (char 1)
+
+
+Command line options
+^^^^^^^^^^^^^^^^^^^^
+
+.. cmdoption:: [<infile>]
+
+   The JSON file to be validated or pretty-printed::
+
+      $ python -m json.tool mp_films.json
+      [
+          {
+              "title": "And Now for Something Completely Different",
+              "year": 1971
+          },
+          {
+              "title": "Monty Python and the Holy Grail",
+              "year": 1975
+          }
+      ]
+
+.. cmdoption:: [<outfile>]
+
+   Write the output of the *infile* to the given *outfile*. Otherwise, write it
+   to :attr:`sys.stdout`.
+
+.. cmdoption:: -h, --help
+
+   Show the help message.
index 7db45285713b63c5890b52aea302ad8d144adcf3..cd57e4f5ae0a33cfaadcf681a69774e83acda283 100644 (file)
@@ -10,21 +10,24 @@ Usage::
     Expecting property name enclosed in double quotes: line 1 column 3 (char 2)
 
 """
-import sys
+import argparse
 import json
+import sys
+
 
 def main():
-    if len(sys.argv) == 1:
-        infile = sys.stdin
-        outfile = sys.stdout
-    elif len(sys.argv) == 2:
-        infile = open(sys.argv[1], 'r')
-        outfile = sys.stdout
-    elif len(sys.argv) == 3:
-        infile = open(sys.argv[1], 'r')
-        outfile = open(sys.argv[2], 'w')
-    else:
-        raise SystemExit(sys.argv[0] + " [infile [outfile]]")
+    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')
+    options = parser.parse_args()
+
+    infile = options.infile or sys.stdin
+    outfile = options.outfile or sys.stdout
     with infile:
         try:
             obj = json.load(infile)
index 0c39e56837ba1672cae8b8d1f2e8db4b2ee9fd16..5484a8a7ca105fb820433416c2ebdb2d30174a28 100644 (file)
@@ -55,6 +55,7 @@ class TestTool(unittest.TestCase):
     def test_infile_stdout(self):
         infile = self._create_infile()
         rc, out, err = assert_python_ok('-m', 'json.tool', infile)
+        self.assertEqual(rc, 0)
         self.assertEqual(out.splitlines(), self.expect.encode().splitlines())
         self.assertEqual(err, b'')
 
@@ -65,5 +66,12 @@ class TestTool(unittest.TestCase):
         self.addCleanup(os.remove, outfile)
         with open(outfile, "r") as fp:
             self.assertEqual(fp.read(), self.expect)
+        self.assertEqual(rc, 0)
         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'')
index 73ca802ffa20aa83ded4bf4e3418da06801a5a87..ade246c340b252ac149a9bd23f35bc29be09c67d 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -23,6 +23,8 @@ Core and Builtins
 Library
 -------
 
+- Issue #21000: Improve the command-line interface of json.tool.
+
 - Issue #20995: Enhance default ciphers used by the ssl module to enable
   better security an prioritize perfect forward secrecy.