This report is out-of-date.

The state of things has changed dramatically, for the better, since I first wrote this in early 2008. Although my test cases are still quite useful, any information regarding specific python packages is likely to be inaccurate. I am leaving these pages here primarily for historic interest.

Sequences

For these tests, the following Python definitions will be used:

# Generator
def gen3():
    yield 1; yield 2; yield 3

# Array
import array
arr = array.array('i', [1,2,3])

# Deque
import collections
deq = collections.deque()
deq.append(1); deq.append(2); deq.append(3)

# Default dict
defdict = collections.defaultdict( lambda: 9 )
defdict["a"] = 42

# UserList
import UserList
ulist = UserList.UserList()
ulist.append(1); ulist.append(2); ulist.append(3)

# UserDict
import UserDict
udict = UserDict.UserDict()
udict["a"] = 42

# Cyclic data structure
cyclic = [42]
cyclic.append( cyclic )

Converting Python sequences to JSON

Diversity of sequence and map types

These tests determine which standard Python collection or sequence-like types can be automatically converted into a reasonable JSON representation. Clearly all JSON modules must handle the builtin list, tuple, and dict types; with other types perhaps being less important. It is also important that Python's str and unicode types are never interpreted as being sequences for the purposes of JSON output.

Both the demjson and simplejson modules have documented extension techniques to allow them to handle additional types that they may not be able to handle by default.

For unordered Python types such as set and frozenset we do not necessarily care about the order (or lack thereof) in which the elements are output in the generated JSON. Similarly for dictionaries, the order in which dict items are placed into JSON object members is also unimportant. Some modules though may perform sorting by keys either by default (demjson), or by caller option (jsonlib and simplejson).

Table 1: Supported Python sequences and containers to JSON
Test# from Python to JSON demjson jsonlib python-cjson python-json simplejson
1–1 [] [] yes yes yes yes yes
1–2 () [] yes yes yes yes yes
1–3 {} {} yes yes yes yes yes
1–4 [1,2,3] [1,2,3] yes yes yes yes yes
1–5 (1,2,3) [1,2,3] yes yes yes yes yes
1–6 {"a":1} {'a':1} yes yes yes yes yes
1–7 set([1,5,10]) [1,10,5] yes no no no no
1–8 frozenset([1,5,
10])
[1,10,5] yes no no no no
1–9 gen3() [1,2,3] yes no no no no
1–10 arr [1,2,3] yes no no no no
1–11 deq [1,2,3] yes no no no no
1–12 ulist [1,2,3] yes no no no no
1–13 defdict {"a":42} yes no yes no yes
1–14 udict {"a":42} yes no no no no

Nesting depth

The next tests are used to determine the limits of nesting. JSON itself imposes no limit on how deeply objects can be nested, but allows implementations to do so. Some of the Python implementations have limits; particularly those that rely on recursion.

Notation: The notation [...x...] means a nested list which is x lists deep; e.g., [...3...] really means [[[]]]. On the system used for testing, the sys.getrecursionlimit() == 1000. Also the testing framework used 2 additional stack slots.

Table 2: Nested Python lists to JSON
Test# from Python to JSON demjson jsonlib python-cjson python-json simplejson
2–1 [[]] [[]] yes yes yes yes yes
2–2 [[[]]] [[[]]] yes yes yes yes yes
2–3 [...497...] [...497...] yes yes, but SLOW yes yes yes
2–4 [...498...] [...498...] no no yes yes no
2–5 [...994...] [...994...] no no yes yes no
2–6 [...995...] [...995...] no no yes no no
2–7 [...5000...] [...5000...] no no yes no no

Cyclic structure protection

In python it is possible to create cyclic data structures. Obviously these are not representable in JSON. However it may be desirable for a module attempting to convert such a cyclic object into JSON to abort with an error; it certainly should not get stuck in an infinite loop and ideally should not depend upon recursion stack exhaustion.

Note that the simplejson module performs cyclic structure detection by default, but it is possible to disable that feature (for performance) by invoking it as such:

# Disabling cycle detection in simplejson
json_ustr = simplejson.dumps( pyobject, check_circular=False )

Both demjson and python-cjson always perform cycle checks. The python-json module never does them, instead relying on the recusrion stack to overflow.

Table 3: Handling of cyclic data structures
Test# from Python to JSON demjson jsonlib python-cjson python-json simplejson
3–1 cyclic n/a yes: raises JSONEncodeError yes: raises jsonlib.errors.WriteError yes: raises EncodeError no: maximum recursion depth exceeded yes: raises ValueError

Go to the next page: Strings