Skip to content

Commit 4c3cc8f

Browse files
authored
Merge pull request #184 from ushuz/pretty-json-no-ensure-ascii
Add --no-ensure-ascii option to pretty-format-json hook
2 parents 414cfa7 + 10f8bd2 commit 4c3cc8f

File tree

3 files changed

+41
-10
lines changed

3 files changed

+41
-10
lines changed

pre_commit_hooks/pretty_format_json.py

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,35 @@
11
from __future__ import print_function
22

33
import argparse
4+
import io
45
import sys
56
from collections import OrderedDict
67

78
import simplejson
9+
import six
810

911

10-
def _get_pretty_format(contents, indent, sort_keys=True, top_keys=[]):
12+
def _get_pretty_format(contents, indent, ensure_ascii=True, sort_keys=True, top_keys=[]):
1113
def pairs_first(pairs):
1214
before = [pair for pair in pairs if pair[0] in top_keys]
1315
before = sorted(before, key=lambda x: top_keys.index(x[0]))
1416
after = [pair for pair in pairs if pair[0] not in top_keys]
1517
if sort_keys:
1618
after = sorted(after, key=lambda x: x[0])
1719
return OrderedDict(before + after)
18-
return simplejson.dumps(
20+
return six.text_type(simplejson.dumps(
1921
simplejson.loads(
2022
contents,
2123
object_pairs_hook=pairs_first,
2224
),
23-
indent=indent
24-
) + "\n" # dumps don't end with a newline
25+
indent=indent,
26+
ensure_ascii=ensure_ascii
27+
)) + "\n" # dumps don't end with a newline
2528

2629

27-
def _autofix(filename, new_contents):
30+
def _autofix(filename, new_contents, encoding=None):
2831
print("Fixing file {}".format(filename))
29-
with open(filename, 'w') as f:
32+
with io.open(filename, 'w', encoding=encoding) as f:
3033
f.write(new_contents)
3134

3235

@@ -69,6 +72,13 @@ def pretty_format_json(argv=None):
6972
default=' ',
7073
help='String used as delimiter for one indentation level',
7174
)
75+
parser.add_argument(
76+
'--no-ensure-ascii',
77+
action='store_true',
78+
dest='no_ensure_ascii',
79+
default=False,
80+
help='Do NOT convert non-ASCII characters to Unicode escape sequences (\\uXXXX)',
81+
)
7282
parser.add_argument(
7383
'--no-sort-keys',
7484
action='store_true',
@@ -90,20 +100,23 @@ def pretty_format_json(argv=None):
90100
status = 0
91101

92102
for json_file in args.filenames:
93-
with open(json_file) as f:
103+
with io.open(json_file, encoding='utf-8') as f:
94104
contents = f.read()
95105

96106
try:
97107
pretty_contents = _get_pretty_format(
98-
contents, args.indent, sort_keys=not args.no_sort_keys,
99-
top_keys=args.top_keys
108+
contents, args.indent, ensure_ascii=not args.no_ensure_ascii,
109+
sort_keys=not args.no_sort_keys, top_keys=args.top_keys
100110
)
101111

102112
if contents != pretty_contents:
103113
print("File {} is not pretty-formatted".format(json_file))
104114

105115
if args.autofix:
106-
_autofix(json_file, pretty_contents)
116+
_autofix(
117+
json_file, pretty_contents,
118+
encoding='utf-8' if args.no_ensure_ascii else None
119+
)
107120

108121
status = 1
109122

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"alist": [
3+
2,
4+
34,
5+
234
6+
],
7+
"blah": null,
8+
"foo": "bar",
9+
"non_ascii": "中文にほんご한국어"
10+
}

tests/pretty_format_json_test.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ def test_parse_indent():
2020
@pytest.mark.parametrize(('filename', 'expected_retval'), (
2121
('not_pretty_formatted_json.json', 1),
2222
('unsorted_pretty_formatted_json.json', 1),
23+
('non_ascii_pretty_formatted_json.json', 1),
2324
('pretty_formatted_json.json', 0),
2425
))
2526
def test_pretty_format_json(filename, expected_retval):
@@ -30,6 +31,7 @@ def test_pretty_format_json(filename, expected_retval):
3031
@pytest.mark.parametrize(('filename', 'expected_retval'), (
3132
('not_pretty_formatted_json.json', 1),
3233
('unsorted_pretty_formatted_json.json', 0),
34+
('non_ascii_pretty_formatted_json.json', 1),
3335
('pretty_formatted_json.json', 0),
3436
))
3537
def test_unsorted_pretty_format_json(filename, expected_retval):
@@ -40,6 +42,7 @@ def test_unsorted_pretty_format_json(filename, expected_retval):
4042
@pytest.mark.parametrize(('filename', 'expected_retval'), (
4143
('not_pretty_formatted_json.json', 1),
4244
('unsorted_pretty_formatted_json.json', 1),
45+
('non_ascii_pretty_formatted_json.json', 1),
4346
('pretty_formatted_json.json', 1),
4447
('tab_pretty_formatted_json.json', 0),
4548
))
@@ -48,6 +51,11 @@ def test_tab_pretty_format_json(filename, expected_retval):
4851
assert ret == expected_retval
4952

5053

54+
def test_non_ascii_pretty_format_json():
55+
ret = pretty_format_json(['--no-ensure-ascii', get_resource_path('non_ascii_pretty_formatted_json.json')])
56+
assert ret == 0
57+
58+
5159
def test_autofix_pretty_format_json(tmpdir):
5260
srcfile = tmpdir.join('to_be_json_formatted.json')
5361
shutil.copyfile(

0 commit comments

Comments
 (0)