Skip to content
/ chjson Public

Developer friendly JSON codec for Python -- supports comments, trailing commas, and more!

License

Notifications You must be signed in to change notification settings

landonb/chjson

Repository files navigation

chjson

The chjson Python C extension implements a developer friendly JSON codec.

In addition to the machine-centric JSON standard, it accepts developer-pleasing syntax:

  • Single- // and multi-line /* */ comments.
  • Trailing commas ,
  • Single-quoted '' object keys (as opposed to requiring double-quotes).
  • Fractional numbers without a leading zero, like .123.
  • Multi-line strings -- either use a line continuation character at the end of lines (and it and the newline will be removed from the string), or just start a new line before the string closing quote (and the newline will be left in the string).

And it reports the line number and character offset on error.

This module works in Python 2.7, 3.3, and 3.4.

It should be easy to adapt to other versions as necessary.

The module is derived from Dan Pascu's Python2 module, python-cjson 1.1.0.

See also Hjson, the Human JSON, a pure-py implementation with a very rich syntax..

Usage example

Simple encoding and decoding string example:

>>> import chjson
>>> chjson.encode({'q': True, '23': None,})
'{"q": true, "23": null}'
>>> chjson.decode('{"q": true, "23": null /* ignored \n */ , \'abc\': .123, } // ignored')
{'23': None, 'q': True, 'abc': 0.123}

Simple file decoding example:

>>> try:
...     chjson.decode(open(json_path, 'r').read())
... except chjson.DecodeError as e:
...     # Log filename, line number, and column (offset).
...     fatal('Failed to load file "%s": %s' % (json_path, e.args[0],)
...     raise

Strict Mode

Yes, chjson can be tricked into adhering to the exact JSON spec. Just set strict=True.

>>> import chjson
>>> chjson.decode('{"q": true, "23": null,}', strict=True)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
chjson.DecodeError: expecting object property name rather than
    trailing comma at position 23 (lineno 1, offset 23)

Performance

The author tested this plugin against demjson (the only comparable loose (developer-friendly) JSON codec) on 2015.09.25 and saw a seven times improvement in performance over demjson for a real-world usage scenario involving reading JSON files in Python, parsing them with either demjson or chjson, and checking all dictionary values to see if they indicate a JSON path that should be side-loaded. (Read: chjson is faster than demjson by around a factor, but it'll depend on your usage scenario.) In real-world numbers, application boot time decreased from 6.65 seconds to 0.95 for this scenario. Not a crazy gain but enough to ease development pains.

Compilation

Prerequisites

You'll at least need a C compiler and the Python headers.

sudo apt-get install -y libpython3-dev

Debug Build

From the source directory, to make a debug build, try:

/bin/rm -rf build/ dist/ python_chjson.egg-info/
python3 ./setup.py clean
CFLAGS='-Wall -O0 -g' python3 ./setup.py build
python3 ./setup.py install

and then, e.g.,

gdb python3
b JSON_decode
run
import chjson
chjson.decode('{"my": "example",} // ignored')

And if you want a python2 build, do it all over again.

/bin/rm -rf build/ dist/ python_chjson.egg-info/
python2 ./setup.py clean
CFLAGS='-Wall -O0 -g' python2 ./setup.py build
python2 ./setup.py install

Production Build

Omit the CFLAGS to make a production build, 'natch.

Troubleshooting

If the Python2 binary builds but fails to load when imported, you may have built with Python3 libraries on your path. Try this:

CPPFLAGS='' LDFLAGS='' python2 ./setup.py build

Additional Information

Some articles on JSON performance in Python:

Some articles on writing C Python extensions:

About

Developer friendly JSON codec for Python -- supports comments, trailing commas, and more!

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published