Skip to content
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

Add the option to iteratively encode JSON. #29

Merged
merged 7 commits into from
Aug 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
11 changes: 10 additions & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
35 changes: 34 additions & 1 deletion canonicaljson.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
6 changes: 6 additions & 0 deletions test_canonicaljson.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
from canonicaljson import (
encode_canonical_json,
encode_pretty_printed_json,
iterencode_canonical_json,
iterencode_pretty_printed_json,
set_json_library,
)

Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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(
Expand Down