diff --git a/README.rst b/README.rst index c3c1b2c..a6887d6 100644 --- a/README.rst +++ b/README.rst @@ -34,12 +34,21 @@ Installing Using ----- +To encode an object into the canonicaljson: + .. code:: python import canonicaljson assert canonicaljson.encode_canonical_json({}) == b'{}' -The underlying JSON implementation can be choosen with the following: +There's also an iterator version: + +.. code:: python + + import canonicaljson + assert b''.join(canonicaljson.iterencode_canonical_json({})) == b'{}' + +The underlying JSON implementation can be chosen with the following: .. code:: python diff --git a/canonicaljson.py b/canonicaljson.py index 63118a6..ff594ab 100644 --- a/canonicaljson.py +++ b/canonicaljson.py @@ -75,12 +75,45 @@ def encode_canonical_json(json_object): return s.encode("utf-8") +def iterencode_canonical_json(json_object): + """Encodes the shortest UTF-8 JSON encoding with dictionary keys + lexicographically sorted by unicode code point. + + Args: + json_object (dict): The JSON object to encode. + + Returns: + generator which yields bytes encoding the JSON object""" + for chunk in _canonical_encoder.iterencode(json_object): + yield chunk.encode("utf-8") + + def encode_pretty_printed_json(json_object): - """Encodes the JSON object dict as human readable ascii bytes.""" + """ + Encodes the JSON object dict as human readable ascii bytes. + + Args: + json_object (dict): The JSON object to encode. + + Returns: + bytes encoding the JSON object""" return _pretty_encoder.encode(json_object).encode("ascii") +def iterencode_pretty_printed_json(json_object): + """Encodes the JSON object dict as human readable ascii bytes. + + Args: + json_object (dict): The JSON object to encode. + + Returns: + generator which yields bytes encoding the JSON object""" + + for chunk in _pretty_encoder.iterencode(json_object): + yield chunk.encode("ascii") + + if platform.python_implementation() == "PyPy": # pragma: no cover # pypy ships with an optimised JSON encoder/decoder that is faster than # simplejson's C extension. diff --git a/test_canonicaljson.py b/test_canonicaljson.py index d06c66a..6f45092 100644 --- a/test_canonicaljson.py +++ b/test_canonicaljson.py @@ -18,6 +18,8 @@ from canonicaljson import ( encode_canonical_json, encode_pretty_printed_json, + iterencode_canonical_json, + iterencode_pretty_printed_json, set_json_library, ) @@ -62,6 +64,9 @@ def test_encode_canonical(self): b'"\\\\u1234"', ) + # Iteratively encoding should work. + self.assertEqual(list(iterencode_canonical_json({})), [b'{}']) + def test_ascii(self): """ Ensure the proper ASCII characters are escaped. @@ -101,6 +106,7 @@ def test_ascii(self): def test_encode_pretty_printed(self): self.assertEqual(encode_pretty_printed_json({}), b'{}') + self.assertEqual(list(iterencode_pretty_printed_json({})), [b'{}']) def test_frozen_dict(self): self.assertEqual(