Skip to content

Commit e40bd75

Browse files
authored
Add the option to iteratively encode JSON. (#29)
1 parent 7e16350 commit e40bd75

File tree

3 files changed

+50
-2
lines changed

3 files changed

+50
-2
lines changed

README.rst

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,21 @@ Installing
3434
Using
3535
-----
3636

37+
To encode an object into the canonicaljson:
38+
3739
.. code:: python
3840
3941
import canonicaljson
4042
assert canonicaljson.encode_canonical_json({}) == b'{}'
4143
42-
The underlying JSON implementation can be choosen with the following:
44+
There's also an iterator version:
45+
46+
.. code:: python
47+
48+
import canonicaljson
49+
assert b''.join(canonicaljson.iterencode_canonical_json({})) == b'{}'
50+
51+
The underlying JSON implementation can be chosen with the following:
4352

4453
.. code:: python
4554

canonicaljson.py

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,45 @@ def encode_canonical_json(json_object):
7575
return s.encode("utf-8")
7676

7777

78+
def iterencode_canonical_json(json_object):
79+
"""Encodes the shortest UTF-8 JSON encoding with dictionary keys
80+
lexicographically sorted by unicode code point.
81+
82+
Args:
83+
json_object (dict): The JSON object to encode.
84+
85+
Returns:
86+
generator which yields bytes encoding the JSON object"""
87+
for chunk in _canonical_encoder.iterencode(json_object):
88+
yield chunk.encode("utf-8")
89+
90+
7891
def encode_pretty_printed_json(json_object):
79-
"""Encodes the JSON object dict as human readable ascii bytes."""
92+
"""
93+
Encodes the JSON object dict as human readable ascii bytes.
94+
95+
Args:
96+
json_object (dict): The JSON object to encode.
97+
98+
Returns:
99+
bytes encoding the JSON object"""
80100

81101
return _pretty_encoder.encode(json_object).encode("ascii")
82102

83103

104+
def iterencode_pretty_printed_json(json_object):
105+
"""Encodes the JSON object dict as human readable ascii bytes.
106+
107+
Args:
108+
json_object (dict): The JSON object to encode.
109+
110+
Returns:
111+
generator which yields bytes encoding the JSON object"""
112+
113+
for chunk in _pretty_encoder.iterencode(json_object):
114+
yield chunk.encode("ascii")
115+
116+
84117
if platform.python_implementation() == "PyPy": # pragma: no cover
85118
# pypy ships with an optimised JSON encoder/decoder that is faster than
86119
# simplejson's C extension.

test_canonicaljson.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
from canonicaljson import (
1919
encode_canonical_json,
2020
encode_pretty_printed_json,
21+
iterencode_canonical_json,
22+
iterencode_pretty_printed_json,
2123
set_json_library,
2224
)
2325

@@ -62,6 +64,9 @@ def test_encode_canonical(self):
6264
b'"\\\\u1234"',
6365
)
6466

67+
# Iteratively encoding should work.
68+
self.assertEqual(list(iterencode_canonical_json({})), [b'{}'])
69+
6570
def test_ascii(self):
6671
"""
6772
Ensure the proper ASCII characters are escaped.
@@ -101,6 +106,7 @@ def test_ascii(self):
101106

102107
def test_encode_pretty_printed(self):
103108
self.assertEqual(encode_pretty_printed_json({}), b'{}')
109+
self.assertEqual(list(iterencode_pretty_printed_json({})), [b'{}'])
104110

105111
def test_frozen_dict(self):
106112
self.assertEqual(

0 commit comments

Comments
 (0)