10000 gh-122873: Allow "python3 -m json" to work by treyhunner · Pull Request #122884 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

gh-122873: Allow "python3 -m json" to work #122884

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 24 commits into from
Aug 13, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
27e449d
Rename json.tool to json.__main__
treyhunner Aug 1, 2024
423c971
Make json.tool delegate to json.__main__
treyhunner Aug 1, 2024
1c1a8fa
Note json.tool deprecation
treyhunner Aug 1, 2024
f8f6931
Move main function from json.__main__ to json.tool
treyhunner Aug 2, 2024
834fbd7
Remove deprecation warning
treyhunner Aug 9, 2024
62afcf1
Fix module name as shown at command-line
treyhunner Aug 10, 2024
f58e60a
Update docs and what's new for json.tool to json
treyhunner Aug 10, 2024
168082a
Remove duplicate json module description from docs
treyhunner Aug 10, 2024
52039ee
Give up on marking `-m` as an option
treyhunner Aug 10, 2024
2e37475
Remove unnecessary newline in changed note
treyhunner Aug 10, 2024
efd0503
Remove now-invalid json.tool module reference
treyhunner Aug 10, 2024
c6bb211
Add news entry with blurb
treyhunner Aug 10, 2024
e768e39
Remove older raw string usage in docstring
treyhunner Aug 10, 2024
a6b5c0d
Use sentence case in section title
treyhunner Aug 10, 2024
8000 3105bc2
Add CLI invocation for easier copy-pasting
treyhunner Aug 10, 2024
238fc57
Update json.__init__ docstring for python -m json
treyhunner Aug 10, 2024
7f704bf
Note `python -m json` in What's New
treyhunner Aug 10, 2024
fba68ac
Use SystemExit consistently in json package
treyhunner Aug 10, 2024
8662c81
Improve grammar in news
treyhunner Aug 12, 2024
52129e6
Add json.tool submodule documentation reference back in.
treyhunner Aug 12, 2024
016206d
Note that json.tool still works for compatibility reasons
treyhunner Aug 12, 2024
9b22285
Note that json.tool implements the CLI
treyhunner Aug 12, 2024
9fd0c1c
Reference json.__main__ in json.tool docstring
treyhunner Aug 12, 2024
734fbf9
Switch json.tool to json on listing of Python CLIs
treyhunner Aug 13, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Move main function from json.__main__ to json.tool
  • Loading branch information
treyhunner committed Aug 10, 2024
commit f8f69315ba0ed7d3257ff787e98f3aa6bc05b7e6
76 changes: 4 additions & 72 deletions Lib/json/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,88 +2,20 @@

Usage::

$ echo '{"json":"obj"}' | python -m json.tool
$ echo '{"json":"obj"}' | python -m json
{
"json": "obj"
}
$ echo '{ 1.2:3.4}' | python -m json.tool
$ echo '{ 1.2:3.4}' | python -m json
Expecting property name enclosed in double quotes: line 1 column 3 (char 2)

"""
import argparse
import json
import json.tool
import sys


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='?',
help='a JSON file to be validated or pretty-printed',
default='-')
parser.add_argument('outfile', nargs='?',
help='write the output of infile to outfile',
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',
help='disable escaping of non-ASCII characters')
parser.add_argument('--json-lines', action='store_true', default=False,
help='parse input using the JSON Lines format. '
'Use with --no-indent or --compact to produce valid JSON Lines output.')
group = parser.add_mutually_exclusive_group()
group.add_argument('--indent', default=4, type=int,
help='separate items with newlines and use this number '
'of spaces for indentation')
group.add_argument('--tab', action='store_const', dest='indent',
const='\t', help='separate items with newlines and use '
'tabs for indentation')
group.add_argument('--no-indent', action='store_const', dest='indent',
const=None,
help='separate items with spaces rather than newlines')
group.add_argument('--compact', action='store_true',
help='suppress all whitespace separation (most compact)')
options = parser.parse_args()

dump_args = {
'sort_keys': options.sort_keys,
'indent': options.indent,
'ensure_ascii': options.ensure_ascii,
}
if options.compact:
dump_args['indent'] = None
dump_args['separators'] = ',', ':'

try:
if options.infile == '-':
infile = sys.stdin
else:
infile = open(options.infile, encoding='utf-8')
try:
if options.json_lines:
objs = (json.loads(line) for line in infile)
else:
objs = (json.load(infile),)
finally:
if infile is not sys.stdin:
infile.close()

if options.outfile is None:
outfile = sys.stdout
else:
outfile = open(options.outfile, 'w', encoding='utf-8')
with outfile:
for obj in objs:
json.dump(obj, outfile, **dump_args)
outfile.write('\n')
except ValueError as e:
raise SystemExit(e)


if __name__ == '__main__':
try:
main()
json.tool.main()
except BrokenPipeError as exc:
sys.exit(exc.errno)
72 changes: 67 additions & 5 deletions Lib/json/tool.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,78 @@
import argparse
import json
import sys
import warnings

from . import __main__


def main():
warnings.warn('The json.tool module is deprecated',
DeprecationWarning, stacklevel=2)
__main__.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='?',
help='a JSON file to be validated or pretty-printed',
default='-')
parser.add_argument('outfile', nargs='?',
help='write the output of infile to outfile',
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',
help='disable escaping of non-ASCII characters')
parser.add_argument('--json-lines', action='store_true', default=False,
help='parse input using the JSON Lines format. '
'Use with --no-indent or --compact to produce valid JSON Lines output.')
group = parser.add_mutually_exclusive_group()
group.add_argument('--indent', default=4, type=int,
help='separate items with newlines and use this number '
'of spaces for indentation')
group.add_argument('--tab', action='store_const', dest='indent',
const='\t', help='separate items with newlines and use '
'tabs for indentation')
group.add_argument('--no-indent', action='store_const', dest='indent',
const=None,
help='separate items with spaces rather than newlines')
group.add_argument('--compact', action='store_true',
help='suppress all whitespace separation (most compact)')
options = parser.parse_args()

dump_args = {
'sort_keys': options.sort_keys,
'indent': options.indent,
'ensure_ascii': options.ensure_ascii,
}
if options.compact:
dump_args['indent'] = None
dump_args['separators'] = ',', ':'

try:
if options.infile == '-':
infile = sys.stdin
else:
infile = open(options.infile, encoding='utf-8')
try:
if options.json_lines:
objs = (json.loads(line) for line in infile)
else:
objs = (json.load(infile),)
finally:
if infile is not sys.stdin:
infile.close()

if options.outfile is None:
outfile = sys.stdout
else:
outfile = open(options.outfile, 'w', encoding='utf-8')
with outfile:
for obj in objs:
json.dump(obj, outfile, **dump_args)
outfile.write('\n')
except ValueError as e:
raise SystemExit(e)


if __name__ == '__main__':
warnings.warn('The json.tool module is deprecated', DeprecationWarning)
try:
main()
except BrokenPipeError as exc:
Expand Down
3 changes: 2 additions & 1 deletion Lib/test/test_json/test_tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -254,4 +254,5 @@ def test_with_warnings(self):
rc, out, err = assert_python_ok('-m', self.module, infile)
self.assertEqual(rc, 0)
self.assertEqual(out.splitlines(), self.expect.encode().splitlines())
self.assertEqual(err.decode(), f'{filename}:15: DeprecationWarning: The json.tool module is deprecated\n main()\n')
self.assertRegex(err.decode(),
r'^.+/json/tool\.py:\d+: DeprecationWarning: The json.tool module is deprecated\n.+\n$')
0